summaryrefslogtreecommitdiff
path: root/chromium/net/http
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-10-13 13:24:50 +0200
committerAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-10-14 10:57:25 +0000
commitaf3d4809763ef308f08ced947a73b624729ac7ea (patch)
tree4402b911e30383f6c6dace1e8cf3b8e85355db3a /chromium/net/http
parent0e8ff63a407fe323e215bb1a2c423c09a4747c8a (diff)
downloadqtwebengine-chromium-af3d4809763ef308f08ced947a73b624729ac7ea.tar.gz
BASELINE: Update Chromium to 47.0.2526.14
Also adding in sources needed for spellchecking. Change-Id: Idd44170fa1616f26315188970a8d5ba7d472b18a Reviewed-by: Michael BrĂ¼ning <michael.bruning@theqtcompany.com>
Diffstat (limited to 'chromium/net/http')
-rw-r--r--chromium/net/http/des.cc125
-rw-r--r--chromium/net/http/failing_http_transaction_factory.cc14
-rw-r--r--chromium/net/http/http_auth_handler_factory.cc14
-rw-r--r--chromium/net/http/http_auth_handler_factory.h3
-rw-r--r--chromium/net/http/http_auth_handler_ntlm_portable.cc2
-rw-r--r--chromium/net/http/http_auth_multi_round_parse.cc2
-rw-r--r--chromium/net/http/http_basic_stream.cc23
-rw-r--r--chromium/net/http/http_basic_stream.h12
-rw-r--r--chromium/net/http/http_cache.h1
-rw-r--r--chromium/net/http/http_cache_transaction.cc1106
-rw-r--r--chromium/net/http/http_cache_transaction.h114
-rw-r--r--chromium/net/http/http_cache_unittest.cc459
-rw-r--r--chromium/net/http/http_content_disposition.cc16
-rw-r--r--chromium/net/http/http_log_util.cc16
-rw-r--r--chromium/net/http/http_network_layer.cc8
-rw-r--r--chromium/net/http/http_network_layer.h8
-rw-r--r--chromium/net/http/http_network_layer_unittest.cc4
-rw-r--r--chromium/net/http/http_network_session.cc13
-rw-r--r--chromium/net/http/http_network_session.h9
-rw-r--r--chromium/net/http/http_network_transaction.cc131
-rw-r--r--chromium/net/http/http_network_transaction.h16
-rw-r--r--chromium/net/http/http_network_transaction_ssl_unittest.cc2
-rw-r--r--chromium/net/http/http_network_transaction_unittest.cc1193
-rw-r--r--chromium/net/http/http_proxy_client_socket_pool_unittest.cc4
-rw-r--r--chromium/net/http/http_request_headers.cc6
-rw-r--r--chromium/net/http/http_response_body_drainer.h2
-rw-r--r--chromium/net/http/http_response_body_drainer_unittest.cc11
-rw-r--r--chromium/net/http/http_response_headers.cc74
-rw-r--r--chromium/net/http/http_response_headers_unittest.cc4
-rw-r--r--chromium/net/http/http_response_info.cc38
-rw-r--r--chromium/net/http/http_response_info.h5
-rw-r--r--chromium/net/http/http_response_info_unittest.cc24
-rw-r--r--chromium/net/http/http_security_headers.cc195
-rw-r--r--chromium/net/http/http_security_headers.h30
-rw-r--r--chromium/net/http/http_security_headers_unittest.cc429
-rw-r--r--chromium/net/http/http_server_properties.cc5
-rw-r--r--chromium/net/http/http_server_properties.h22
-rw-r--r--chromium/net/http/http_server_properties_impl.cc113
-rw-r--r--chromium/net/http/http_server_properties_impl.h4
-rw-r--r--chromium/net/http/http_server_properties_impl_unittest.cc316
-rw-r--r--chromium/net/http/http_server_properties_manager.cc103
-rw-r--r--chromium/net/http/http_server_properties_manager.h19
-rw-r--r--chromium/net/http/http_server_properties_manager_unittest.cc161
-rw-r--r--chromium/net/http/http_status_line_validator.cc136
-rw-r--r--chromium/net/http/http_status_line_validator.h86
-rw-r--r--chromium/net/http/http_status_line_validator_unittest.cc88
-rw-r--r--chromium/net/http/http_stream.h44
-rw-r--r--chromium/net/http/http_stream_factory.cc58
-rw-r--r--chromium/net/http/http_stream_factory.h9
-rw-r--r--chromium/net/http/http_stream_factory_impl.cc19
-rw-r--r--chromium/net/http/http_stream_factory_impl.h1
-rw-r--r--chromium/net/http/http_stream_factory_impl_job.cc43
-rw-r--r--chromium/net/http/http_stream_factory_impl_job.h8
-rw-r--r--chromium/net/http/http_stream_factory_impl_request_unittest.cc2
-rw-r--r--chromium/net/http/http_stream_factory_impl_unittest.cc70
-rw-r--r--chromium/net/http/http_stream_parser.cc129
-rw-r--r--chromium/net/http/http_stream_parser.h24
-rw-r--r--chromium/net/http/http_stream_parser_unittest.cc234
-rw-r--r--chromium/net/http/http_transaction.h13
-rw-r--r--chromium/net/http/http_transaction_test_util.cc30
-rw-r--r--chromium/net/http/http_transaction_test_util.h18
-rw-r--r--chromium/net/http/http_util.cc121
-rw-r--r--chromium/net/http/http_util.h27
-rw-r--r--chromium/net/http/http_util_unittest.cc48
-rw-r--r--chromium/net/http/mock_http_cache.cc18
-rw-r--r--chromium/net/http/mock_http_cache.h2
-rw-r--r--chromium/net/http/proxy_connect_redirect_http_stream.cc15
-rw-r--r--chromium/net/http/proxy_connect_redirect_http_stream.h12
-rw-r--r--chromium/net/http/transport_security_persister.cc15
-rw-r--r--chromium/net/http/transport_security_persister_unittest.cc34
-rw-r--r--chromium/net/http/transport_security_state.cc242
-rw-r--r--chromium/net/http/transport_security_state.h70
-rw-r--r--chromium/net/http/transport_security_state_static.h5045
-rw-r--r--chromium/net/http/transport_security_state_static.json768
-rw-r--r--chromium/net/http/transport_security_state_unittest.cc536
75 files changed, 8508 insertions, 4313 deletions
diff --git a/chromium/net/http/des.cc b/chromium/net/http/des.cc
index 17aae4da684..874372f3873 100644
--- a/chromium/net/http/des.cc
+++ b/chromium/net/http/des.cc
@@ -9,22 +9,15 @@
#if defined(USE_OPENSSL)
#include <openssl/des.h>
#include "crypto/openssl_util.h"
-#elif defined(USE_NSS_CERTS)
-#include <nss.h>
-#include <pk11pub.h>
-#include "crypto/nss_util.h"
-#elif defined(OS_MACOSX)
+#elif defined(OS_IOS)
#include <CommonCrypto/CommonCryptor.h>
-#elif defined(OS_WIN)
-#include <windows.h>
-#include <wincrypt.h>
-#include "crypto/scoped_capi_types.h"
+#else
+#error "Unknown platform"
#endif
-// The Mac and Windows (CryptoAPI) versions of DESEncrypt are our own code.
-// DESSetKeyParity, DESMakeKey, and the Linux (NSS) version of DESEncrypt are
-// based on mozilla/security/manager/ssl/src/nsNTLMAuthModule.cpp,
-// CVS rev. 1.14.
+// The iOS version of DESEncrypt is our own code.
+// DESSetKeyParity and DESMakeKey are based on
+// mozilla/security/manager/ssl/src/nsNTLMAuthModule.cpp, CVS rev. 1.14.
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
@@ -100,64 +93,7 @@ void DESEncrypt(const uint8* key, const uint8* src, uint8* hash) {
reinterpret_cast<DES_cblock*>(hash), &ks, DES_ENCRYPT);
}
-#elif defined(USE_NSS_CERTS)
-
-void DESEncrypt(const uint8* key, const uint8* src, uint8* hash) {
- CK_MECHANISM_TYPE cipher_mech = CKM_DES_ECB;
- PK11SlotInfo* slot = NULL;
- PK11SymKey* symkey = NULL;
- PK11Context* ctxt = NULL;
- SECItem key_item;
- SECItem* param = NULL;
- SECStatus rv;
- unsigned int n;
-
- crypto::EnsureNSSInit();
-
- slot = PK11_GetInternalSlot();
- if (!slot)
- goto done;
-
- key_item.data = const_cast<uint8*>(key);
- key_item.len = 8;
- symkey = PK11_ImportSymKey(slot, cipher_mech,
- PK11_OriginUnwrap, CKA_ENCRYPT,
- &key_item, NULL);
- if (!symkey)
- goto done;
-
- // No initialization vector required.
- param = PK11_ParamFromIV(cipher_mech, NULL);
- if (!param)
- goto done;
-
- ctxt = PK11_CreateContextBySymKey(cipher_mech, CKA_ENCRYPT,
- symkey, param);
- if (!ctxt)
- goto done;
-
- rv = PK11_CipherOp(ctxt, hash, reinterpret_cast<int*>(&n), 8,
- const_cast<uint8*>(src), 8);
- if (rv != SECSuccess)
- goto done;
-
- // TODO(wtc): Should this be PK11_Finalize?
- rv = PK11_DigestFinal(ctxt, hash+8, &n, 0);
- if (rv != SECSuccess)
- goto done;
-
- done:
- if (ctxt)
- PK11_DestroyContext(ctxt, PR_TRUE);
- if (symkey)
- PK11_FreeSymKey(symkey);
- if (param)
- SECITEM_FreeItem(param, PR_TRUE);
- if (slot)
- PK11_FreeSlot(slot);
-}
-
-#elif defined(OS_MACOSX)
+#elif defined(OS_IOS)
void DESEncrypt(const uint8* key, const uint8* src, uint8* hash) {
CCCryptorStatus status;
@@ -168,53 +104,6 @@ void DESEncrypt(const uint8* key, const uint8* src, uint8* hash) {
DCHECK(data_out_moved == 8);
}
-#elif defined(OS_WIN)
-
-void DESEncrypt(const uint8* key, const uint8* src, uint8* hash) {
- crypto::ScopedHCRYPTPROV provider;
- if (!CryptAcquireContext(provider.receive(), NULL, NULL, PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT))
- return;
-
- {
- // Import the DES key.
- struct KeyBlob {
- BLOBHEADER header;
- DWORD key_size;
- BYTE key_data[8];
- };
- KeyBlob key_blob;
- key_blob.header.bType = PLAINTEXTKEYBLOB;
- key_blob.header.bVersion = CUR_BLOB_VERSION;
- key_blob.header.reserved = 0;
- key_blob.header.aiKeyAlg = CALG_DES;
- key_blob.key_size = 8; // 64 bits
- memcpy(key_blob.key_data, key, 8);
-
- crypto::ScopedHCRYPTKEY key;
- BOOL import_ok = CryptImportKey(provider,
- reinterpret_cast<BYTE*>(&key_blob),
- sizeof key_blob, 0, 0, key.receive());
- // Destroy the copy of the key.
- SecureZeroMemory(key_blob.key_data, sizeof key_blob.key_data);
- if (!import_ok)
- return;
-
- // No initialization vector required.
- DWORD cipher_mode = CRYPT_MODE_ECB;
- if (!CryptSetKeyParam(key, KP_MODE, reinterpret_cast<BYTE*>(&cipher_mode),
- 0))
- return;
-
- // CryptoAPI requires us to copy the plaintext to the output buffer first.
- CopyMemory(hash, src, 8);
- // Pass a 'Final' of FALSE, otherwise CryptEncrypt appends one additional
- // block of padding to the data.
- DWORD hash_len = 8;
- CryptEncrypt(key, 0, FALSE, 0, hash, &hash_len, 8);
- }
-}
-
#endif
} // namespace net
diff --git a/chromium/net/http/failing_http_transaction_factory.cc b/chromium/net/http/failing_http_transaction_factory.cc
index 89e5329d5d9..adb96914ad0 100644
--- a/chromium/net/http/failing_http_transaction_factory.cc
+++ b/chromium/net/http/failing_http_transaction_factory.cc
@@ -4,6 +4,8 @@
#include "net/http/failing_http_transaction_factory.h"
+#include <stdint.h>
+
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/location.h"
@@ -48,13 +50,15 @@ class FailingHttpTransaction : public HttpTransaction {
const CompletionCallback& callback) override;
void StopCaching() override;
bool GetFullRequestHeaders(HttpRequestHeaders* headers) const override;
- int64 GetTotalReceivedBytes() const override;
+ int64_t GetTotalReceivedBytes() const override;
+ int64_t GetTotalSentBytes() const override;
void DoneReading() override;
const HttpResponseInfo* GetResponseInfo() const override;
LoadState GetLoadState() const override;
UploadProgress GetUploadProgress() const override;
void SetQuicServerInfo(QuicServerInfo* quic_server_info) override;
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
+ bool GetRemoteEndpoint(IPEndPoint* endpoint) const override;
void SetPriority(RequestPriority priority) override;
void SetWebSocketHandshakeStreamCreateHelper(
WebSocketHandshakeStreamBase::CreateHelper* create_helper) override;
@@ -122,6 +126,10 @@ int64 FailingHttpTransaction::GetTotalReceivedBytes() const {
return 0;
}
+int64_t FailingHttpTransaction::GetTotalSentBytes() const {
+ return 0;
+}
+
void FailingHttpTransaction::DoneReading() {
NOTREACHED();
}
@@ -147,6 +155,10 @@ bool FailingHttpTransaction::GetLoadTimingInfo(
return false;
}
+bool FailingHttpTransaction::GetRemoteEndpoint(IPEndPoint* endpoint) const {
+ return false;
+}
+
void FailingHttpTransaction::SetPriority(RequestPriority priority) {}
void FailingHttpTransaction::SetWebSocketHandshakeStreamCreateHelper(
diff --git a/chromium/net/http/http_auth_handler_factory.cc b/chromium/net/http/http_auth_handler_factory.cc
index 4f09c9f23c9..5a89964a80c 100644
--- a/chromium/net/http/http_auth_handler_factory.cc
+++ b/chromium/net/http/http_auth_handler_factory.cc
@@ -43,11 +43,11 @@ int HttpAuthHandlerFactory::CreatePreemptiveAuthHandlerFromString(
}
// static
-HttpAuthHandlerRegistryFactory* HttpAuthHandlerFactory::CreateDefault(
- HostResolver* host_resolver) {
+scoped_ptr<HttpAuthHandlerRegistryFactory>
+HttpAuthHandlerFactory::CreateDefault(HostResolver* host_resolver) {
DCHECK(host_resolver);
- HttpAuthHandlerRegistryFactory* registry_factory =
- new HttpAuthHandlerRegistryFactory();
+ scoped_ptr<HttpAuthHandlerRegistryFactory> registry_factory =
+ make_scoped_ptr(new HttpAuthHandlerRegistryFactory());
registry_factory->RegisterSchemeFactory(
"basic", new HttpAuthHandlerBasic::Factory());
registry_factory->RegisterSchemeFactory(
@@ -106,7 +106,7 @@ void HttpAuthHandlerRegistryFactory::SetURLSecurityManager(
void HttpAuthHandlerRegistryFactory::RegisterSchemeFactory(
const std::string& scheme,
HttpAuthHandlerFactory* factory) {
- std::string lower_scheme = base::StringToLowerASCII(scheme);
+ std::string lower_scheme = base::ToLowerASCII(scheme);
FactoryMap::iterator it = factory_map_.find(lower_scheme);
if (it != factory_map_.end()) {
delete it->second;
@@ -119,7 +119,7 @@ void HttpAuthHandlerRegistryFactory::RegisterSchemeFactory(
HttpAuthHandlerFactory* HttpAuthHandlerRegistryFactory::GetSchemeFactory(
const std::string& scheme) const {
- std::string lower_scheme = base::StringToLowerASCII(scheme);
+ std::string lower_scheme = base::ToLowerASCII(scheme);
FactoryMap::const_iterator it = factory_map_.find(lower_scheme);
if (it == factory_map_.end()) {
return NULL; // |scheme| is not registered.
@@ -190,7 +190,7 @@ int HttpAuthHandlerRegistryFactory::CreateAuthHandler(
handler->reset();
return ERR_INVALID_RESPONSE;
}
- std::string lower_scheme = base::StringToLowerASCII(scheme);
+ std::string lower_scheme = base::ToLowerASCII(scheme);
FactoryMap::iterator it = factory_map_.find(lower_scheme);
if (it == factory_map_.end()) {
handler->reset();
diff --git a/chromium/net/http/http_auth_handler_factory.h b/chromium/net/http/http_auth_handler_factory.h
index 30b1896ce96..1261bedd567 100644
--- a/chromium/net/http/http_auth_handler_factory.h
+++ b/chromium/net/http/http_auth_handler_factory.h
@@ -115,7 +115,8 @@ class NET_EXPORT HttpAuthHandlerFactory {
// non-NULL. |resolver| must remain valid for the lifetime of the
// HttpAuthHandlerRegistryFactory and any HttpAuthHandlers created by said
// factory.
- static HttpAuthHandlerRegistryFactory* CreateDefault(HostResolver* resolver);
+ static scoped_ptr<HttpAuthHandlerRegistryFactory> CreateDefault(
+ HostResolver* resolver);
private:
// The URL security manager
diff --git a/chromium/net/http/http_auth_handler_ntlm_portable.cc b/chromium/net/http/http_auth_handler_ntlm_portable.cc
index 5e1d5faedc5..54d4492a4bf 100644
--- a/chromium/net/http/http_auth_handler_ntlm_portable.cc
+++ b/chromium/net/http/http_auth_handler_ntlm_portable.cc
@@ -261,7 +261,7 @@ static void LM_Hash(const base::string16& password, uint8* hash) {
// Convert password to OEM character set. We'll just use the native
// filesystem charset.
std::string passbuf = base::SysWideToNativeMB(base::UTF16ToWide(password));
- base::StringToUpperASCII(&passbuf);
+ passbuf = base::ToUpperASCII(passbuf);
passbuf.resize(14, '\0');
uint8 k1[8], k2[8];
diff --git a/chromium/net/http/http_auth_multi_round_parse.cc b/chromium/net/http/http_auth_multi_round_parse.cc
index efee2bbcf65..1d0edac08b8 100644
--- a/chromium/net/http/http_auth_multi_round_parse.cc
+++ b/chromium/net/http/http_auth_multi_round_parse.cc
@@ -17,7 +17,7 @@ bool SchemeIsValid(const std::string& scheme,
// There is no guarantee that challenge->scheme() is valid ASCII, but
// LowerCaseEqualsASCII will do the right thing even if it isn't.
return base::LowerCaseEqualsASCII(challenge->scheme(),
- base::StringToLowerASCII(scheme).c_str());
+ base::ToLowerASCII(scheme));
}
} // namespace
diff --git a/chromium/net/http/http_basic_stream.cc b/chromium/net/http/http_basic_stream.cc
index 0d14e0f9a0e..436127f31b8 100644
--- a/chromium/net/http/http_basic_stream.cc
+++ b/chromium/net/http/http_basic_stream.cc
@@ -67,26 +67,28 @@ bool HttpBasicStream::IsResponseBodyComplete() const {
return parser()->IsResponseBodyComplete();
}
-bool HttpBasicStream::CanFindEndOfResponse() const {
- return parser()->CanFindEndOfResponse();
-}
-
bool HttpBasicStream::IsConnectionReused() const {
return parser()->IsConnectionReused();
}
void HttpBasicStream::SetConnectionReused() { parser()->SetConnectionReused(); }
-bool HttpBasicStream::IsConnectionReusable() const {
- return parser()->IsConnectionReusable();
+bool HttpBasicStream::CanReuseConnection() const {
+ return parser()->CanReuseConnection();
}
-int64 HttpBasicStream::GetTotalReceivedBytes() const {
+int64_t HttpBasicStream::GetTotalReceivedBytes() const {
if (parser())
return parser()->received_bytes();
return 0;
}
+int64_t HttpBasicStream::GetTotalSentBytes() const {
+ if (parser())
+ return parser()->sent_bytes();
+ return 0;
+}
+
bool HttpBasicStream::GetLoadTimingInfo(
LoadTimingInfo* load_timing_info) const {
return state_.connection()->GetLoadTimingInfo(IsConnectionReused(),
@@ -102,7 +104,12 @@ void HttpBasicStream::GetSSLCertRequestInfo(
parser()->GetSSLCertRequestInfo(cert_request_info);
}
-bool HttpBasicStream::IsSpdyHttpStream() const { return false; }
+bool HttpBasicStream::GetRemoteEndpoint(IPEndPoint* endpoint) {
+ if (!state_.connection() || !state_.connection()->socket())
+ return false;
+
+ return state_.connection()->socket()->GetPeerAddress(endpoint) == OK;
+}
void HttpBasicStream::Drain(HttpNetworkSession* session) {
HttpResponseBodyDrainer* drainer = new HttpResponseBodyDrainer(this);
diff --git a/chromium/net/http/http_basic_stream.h b/chromium/net/http/http_basic_stream.h
index 194f7ef6c20..c9428d6fb1f 100644
--- a/chromium/net/http/http_basic_stream.h
+++ b/chromium/net/http/http_basic_stream.h
@@ -9,6 +9,8 @@
#ifndef NET_HTTP_HTTP_BASIC_STREAM_H_
#define NET_HTTP_HTTP_BASIC_STREAM_H_
+#include <stdint.h>
+
#include <string>
#include "base/basictypes.h"
@@ -56,15 +58,15 @@ class HttpBasicStream : public HttpStream {
bool IsResponseBodyComplete() const override;
- bool CanFindEndOfResponse() const override;
-
bool IsConnectionReused() const override;
void SetConnectionReused() override;
- bool IsConnectionReusable() const override;
+ bool CanReuseConnection() const override;
+
+ int64_t GetTotalReceivedBytes() const override;
- int64 GetTotalReceivedBytes() const override;
+ int64_t GetTotalSentBytes() const override;
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
@@ -72,7 +74,7 @@ class HttpBasicStream : public HttpStream {
void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override;
- bool IsSpdyHttpStream() const override;
+ bool GetRemoteEndpoint(IPEndPoint* endpoint) override;
void Drain(HttpNetworkSession* session) override;
diff --git a/chromium/net/http/http_cache.h b/chromium/net/http/http_cache.h
index 8300c29048c..026d476e92f 100644
--- a/chromium/net/http/http_cache.h
+++ b/chromium/net/http/http_cache.h
@@ -170,6 +170,7 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory,
// referenced by |url|, as long as the entry's |expected_response_time| has
// not changed. This method returns without blocking, and the operation will
// be performed asynchronously without any completion notification.
+ // Takes ownership of |buf|.
void WriteMetadata(const GURL& url,
RequestPriority priority,
base::Time expected_response_time,
diff --git a/chromium/net/http/http_cache_transaction.cc b/chromium/net/http/http_cache_transaction.cc
index f2fcf4cb7c4..9dd8458e2e2 100644
--- a/chromium/net/http/http_cache_transaction.cc
+++ b/chromium/net/http/http_cache_transaction.cc
@@ -14,6 +14,7 @@
#include <string>
#include "base/bind.h"
+#include "base/callback_helpers.h"
#include "base/compiler_specific.h"
#include "base/format_macros.h"
#include "base/location.h"
@@ -236,8 +237,8 @@ static bool HeaderMatches(const HttpRequestHeaders& headers,
HttpUtil::ValuesIterator v(header_value.begin(), header_value.end(), ',');
while (v.GetNext()) {
- if (base::LowerCaseEqualsASCII(v.value_begin(), v.value_end(),
- search->value))
+ if (base::LowerCaseEqualsASCII(
+ base::StringPiece(v.value_begin(), v.value_end()), search->value))
return true;
}
}
@@ -255,7 +256,6 @@ HttpCache::Transaction::Transaction(RequestPriority priority, HttpCache* cache)
new_entry_(NULL),
new_response_(NULL),
mode_(NONE),
- target_state_(STATE_NONE),
reading_(false),
invalid_range_(false),
truncated_(false),
@@ -274,6 +274,7 @@ HttpCache::Transaction::Transaction(RequestPriority priority, HttpCache* cache)
write_len_(0),
transaction_pattern_(PATTERN_UNDEFINED),
total_received_bytes_(0),
+ total_sent_bytes_(0),
websocket_handshake_stream_base_create_helper_(NULL),
weak_factory_(this) {
static_assert(HttpCache::Transaction::kNumValidationHeaders ==
@@ -327,7 +328,7 @@ bool HttpCache::Transaction::AddTruncatedFlag() {
DCHECK(mode_ & WRITE || mode_ == NONE);
// Don't set the flag for sparse entries.
- if (partial_.get() && !truncated_)
+ if (partial_ && !truncated_)
return true;
if (!CanResume(true))
@@ -338,7 +339,6 @@ bool HttpCache::Transaction::AddTruncatedFlag() {
return true;
truncated_ = true;
- target_state_ = STATE_NONE;
next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE;
DoLoop(OK);
return true;
@@ -367,6 +367,7 @@ int HttpCache::Transaction::Start(const HttpRequestInfo* request,
DCHECK(!reading_);
DCHECK(!network_trans_.get());
DCHECK(!entry_);
+ DCHECK_EQ(next_state_, STATE_NONE);
if (!cache_.get())
return ERR_UNEXPECTED;
@@ -453,6 +454,7 @@ bool HttpCache::Transaction::IsReadyToRestartForAuth() {
int HttpCache::Transaction::Read(IOBuffer* buf, int buf_len,
const CompletionCallback& callback) {
+ DCHECK_EQ(next_state_, STATE_NONE);
DCHECK(buf);
DCHECK_GT(buf_len, 0);
DCHECK(!callback.is_null());
@@ -473,29 +475,19 @@ int HttpCache::Transaction::Read(IOBuffer* buf, int buf_len,
}
reading_ = true;
- int rv;
-
- switch (mode_) {
- case READ_WRITE:
- DCHECK(partial_.get());
- if (!network_trans_.get()) {
- // We are just reading from the cache, but we may be writing later.
- rv = ReadFromEntry(buf, buf_len);
- break;
- }
- case NONE:
- case WRITE:
- DCHECK(network_trans_.get());
- rv = ReadFromNetwork(buf, buf_len);
- break;
- case READ:
- rv = ReadFromEntry(buf, buf_len);
- break;
- default:
- NOTREACHED();
- rv = ERR_FAILED;
+ read_buf_ = buf;
+ io_buf_len_ = buf_len;
+ if (network_trans_) {
+ DCHECK(mode_ == WRITE || mode_ == NONE ||
+ (mode_ == READ_WRITE && partial_));
+ next_state_ = STATE_NETWORK_READ;
+ } else {
+ DCHECK(mode_ == READ || (mode_ == READ_WRITE && partial_));
+ next_state_ = STATE_CACHE_READ_DATA;
}
+ int rv = DoLoop(OK);
+
if (rv == ERR_IO_PENDING) {
DCHECK(callback_.is_null());
callback_ = callback;
@@ -530,13 +522,20 @@ bool HttpCache::Transaction::GetFullRequestHeaders(
return false;
}
-int64 HttpCache::Transaction::GetTotalReceivedBytes() const {
- int64 total_received_bytes = total_received_bytes_;
+int64_t HttpCache::Transaction::GetTotalReceivedBytes() const {
+ int64_t total_received_bytes = total_received_bytes_;
if (network_trans_)
total_received_bytes += network_trans_->GetTotalReceivedBytes();
return total_received_bytes;
}
+int64_t HttpCache::Transaction::GetTotalSentBytes() const {
+ int64_t total_sent_bytes = total_sent_bytes_;
+ if (network_trans_)
+ total_sent_bytes += network_trans_->GetTotalSentBytes();
+ return total_sent_bytes;
+}
+
void HttpCache::Transaction::DoneReading() {
if (cache_.get() && entry_) {
DCHECK_NE(mode_, UPDATE);
@@ -600,6 +599,18 @@ bool HttpCache::Transaction::GetLoadTimingInfo(
return true;
}
+bool HttpCache::Transaction::GetRemoteEndpoint(IPEndPoint* endpoint) const {
+ if (network_trans_)
+ return network_trans_->GetRemoteEndpoint(endpoint);
+
+ if (!old_remote_endpoint_.address().empty()) {
+ *endpoint = old_remote_endpoint_;
+ return true;
+ }
+
+ return false;
+}
+
void HttpCache::Transaction::SetPriority(RequestPriority priority) {
priority_ = priority;
if (network_trans_)
@@ -644,26 +655,6 @@ void HttpCache::Transaction::GetConnectionAttempts(
//-----------------------------------------------------------------------------
-void HttpCache::Transaction::DoCallback(int rv) {
- DCHECK(rv != ERR_IO_PENDING);
- DCHECK(!callback_.is_null());
-
- read_buf_ = NULL; // Release the buffer before invoking the callback.
-
- // Since Run may result in Read being called, clear callback_ up front.
- CompletionCallback c = callback_;
- callback_.Reset();
- c.Run(rv);
-}
-
-int HttpCache::Transaction::HandleResult(int rv) {
- DCHECK(rv != ERR_IO_PENDING);
- if (!callback_.is_null())
- DoCallback(rv);
-
- return rv;
-}
-
// A few common patterns: (Foo* means Foo -> FooComplete)
//
// 1. Not-cached entry:
@@ -690,8 +681,9 @@ int HttpCache::Transaction::HandleResult(int rv) {
// GetBackend* -> InitEntry -> OpenEntry* -> AddToEntry* -> CacheReadResponse*
// -> CacheDispatchValidation -> BeginPartialCacheValidation() ->
// BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest ->
-// UpdateCachedResponse -> CacheWriteResponse* -> UpdateCachedResponseComplete
-// -> OverwriteCachedResponse -> PartialHeadersReceived
+// UpdateCachedResponse -> CacheWriteUpdatedResponse* ->
+// UpdateCachedResponseComplete -> OverwriteCachedResponse ->
+// PartialHeadersReceived
//
// Read():
// CacheReadData*
@@ -714,8 +706,9 @@ int HttpCache::Transaction::HandleResult(int rv) {
// CacheQueryData* -> ValidateEntryHeadersAndContinue() ->
// StartPartialCacheValidation -> CompletePartialCacheValidation ->
// BeginCacheValidation() -> SendRequest* -> SuccessfulSendRequest ->
-// UpdateCachedResponse -> CacheWriteResponse* -> UpdateCachedResponseComplete
-// -> OverwriteCachedResponse -> PartialHeadersReceived
+// UpdateCachedResponse -> CacheWriteUpdatedResponse* ->
+// UpdateCachedResponseComplete -> OverwriteCachedResponse ->
+// PartialHeadersReceived
//
// Read() 1:
// NetworkRead* -> CacheWriteData*
@@ -804,24 +797,6 @@ int HttpCache::Transaction::DoLoop(int result) {
case STATE_GET_BACKEND_COMPLETE:
rv = DoGetBackendComplete(rv);
break;
- case STATE_SEND_REQUEST:
- DCHECK_EQ(OK, rv);
- rv = DoSendRequest();
- break;
- case STATE_SEND_REQUEST_COMPLETE:
- rv = DoSendRequestComplete(rv);
- break;
- case STATE_SUCCESSFUL_SEND_REQUEST:
- DCHECK_EQ(OK, rv);
- rv = DoSuccessfulSendRequest();
- break;
- case STATE_NETWORK_READ:
- DCHECK_EQ(OK, rv);
- rv = DoNetworkRead();
- break;
- case STATE_NETWORK_READ_COMPLETE:
- rv = DoNetworkReadComplete(rv);
- break;
case STATE_INIT_ENTRY:
DCHECK_EQ(OK, rv);
rv = DoInitEntry();
@@ -833,13 +808,6 @@ int HttpCache::Transaction::DoLoop(int result) {
case STATE_OPEN_ENTRY_COMPLETE:
rv = DoOpenEntryComplete(rv);
break;
- case STATE_CREATE_ENTRY:
- DCHECK_EQ(OK, rv);
- rv = DoCreateEntry();
- break;
- case STATE_CREATE_ENTRY_COMPLETE:
- rv = DoCreateEntryComplete(rv);
- break;
case STATE_DOOM_ENTRY:
DCHECK_EQ(OK, rv);
rv = DoDoomEntry();
@@ -847,6 +815,13 @@ int HttpCache::Transaction::DoLoop(int result) {
case STATE_DOOM_ENTRY_COMPLETE:
rv = DoDoomEntryComplete(rv);
break;
+ case STATE_CREATE_ENTRY:
+ DCHECK_EQ(OK, rv);
+ rv = DoCreateEntry();
+ break;
+ case STATE_CREATE_ENTRY_COMPLETE:
+ rv = DoCreateEntryComplete(rv);
+ break;
case STATE_ADD_TO_ENTRY:
DCHECK_EQ(OK, rv);
rv = DoAddToEntry();
@@ -854,6 +829,31 @@ int HttpCache::Transaction::DoLoop(int result) {
case STATE_ADD_TO_ENTRY_COMPLETE:
rv = DoAddToEntryComplete(rv);
break;
+ case STATE_CACHE_READ_RESPONSE:
+ DCHECK_EQ(OK, rv);
+ rv = DoCacheReadResponse();
+ break;
+ case STATE_CACHE_READ_RESPONSE_COMPLETE:
+ rv = DoCacheReadResponseComplete(rv);
+ break;
+ case STATE_TOGGLE_UNUSED_SINCE_PREFETCH:
+ DCHECK_EQ(OK, rv);
+ rv = DoCacheToggleUnusedSincePrefetch();
+ break;
+ case STATE_TOGGLE_UNUSED_SINCE_PREFETCH_COMPLETE:
+ rv = DoCacheToggleUnusedSincePrefetchComplete(rv);
+ break;
+ case STATE_CACHE_DISPATCH_VALIDATION:
+ DCHECK_EQ(OK, rv);
+ rv = DoCacheDispatchValidation();
+ break;
+ case STATE_CACHE_QUERY_DATA:
+ DCHECK_EQ(OK, rv);
+ rv = DoCacheQueryData();
+ break;
+ case STATE_CACHE_QUERY_DATA_COMPLETE:
+ rv = DoCacheQueryDataComplete(rv);
+ break;
case STATE_START_PARTIAL_CACHE_VALIDATION:
DCHECK_EQ(OK, rv);
rv = DoStartPartialCacheValidation();
@@ -861,10 +861,28 @@ int HttpCache::Transaction::DoLoop(int result) {
case STATE_COMPLETE_PARTIAL_CACHE_VALIDATION:
rv = DoCompletePartialCacheValidation(rv);
break;
+ case STATE_SEND_REQUEST:
+ DCHECK_EQ(OK, rv);
+ rv = DoSendRequest();
+ break;
+ case STATE_SEND_REQUEST_COMPLETE:
+ rv = DoSendRequestComplete(rv);
+ break;
+ case STATE_SUCCESSFUL_SEND_REQUEST:
+ DCHECK_EQ(OK, rv);
+ rv = DoSuccessfulSendRequest();
+ break;
case STATE_UPDATE_CACHED_RESPONSE:
DCHECK_EQ(OK, rv);
rv = DoUpdateCachedResponse();
break;
+ case STATE_CACHE_WRITE_UPDATED_RESPONSE:
+ DCHECK_EQ(OK, rv);
+ rv = DoCacheWriteUpdatedResponse();
+ break;
+ case STATE_CACHE_WRITE_UPDATED_RESPONSE_COMPLETE:
+ rv = DoCacheWriteUpdatedResponseComplete(rv);
+ break;
case STATE_UPDATE_CACHED_RESPONSE_COMPLETE:
rv = DoUpdateCachedResponseComplete(rv);
break;
@@ -872,6 +890,13 @@ int HttpCache::Transaction::DoLoop(int result) {
DCHECK_EQ(OK, rv);
rv = DoOverwriteCachedResponse();
break;
+ case STATE_CACHE_WRITE_RESPONSE:
+ DCHECK_EQ(OK, rv);
+ rv = DoCacheWriteResponse();
+ break;
+ case STATE_CACHE_WRITE_RESPONSE_COMPLETE:
+ rv = DoCacheWriteResponseComplete(rv);
+ break;
case STATE_TRUNCATE_CACHED_DATA:
DCHECK_EQ(OK, rv);
rv = DoTruncateCachedData();
@@ -890,35 +915,6 @@ int HttpCache::Transaction::DoLoop(int result) {
DCHECK_EQ(OK, rv);
rv = DoPartialHeadersReceived();
break;
- case STATE_CACHE_READ_RESPONSE:
- DCHECK_EQ(OK, rv);
- rv = DoCacheReadResponse();
- break;
- case STATE_CACHE_READ_RESPONSE_COMPLETE:
- rv = DoCacheReadResponseComplete(rv);
- break;
- case STATE_CACHE_DISPATCH_VALIDATION:
- DCHECK_EQ(OK, rv);
- rv = DoCacheDispatchValidation();
- break;
- case STATE_TOGGLE_UNUSED_SINCE_PREFETCH:
- DCHECK_EQ(OK, rv);
- rv = DoCacheToggleUnusedSincePrefetch();
- break;
- case STATE_TOGGLE_UNUSED_SINCE_PREFETCH_COMPLETE:
- rv = DoCacheToggleUnusedSincePrefetchComplete(rv);
- break;
- case STATE_CACHE_WRITE_RESPONSE:
- DCHECK_EQ(OK, rv);
- rv = DoCacheWriteResponse();
- break;
- case STATE_CACHE_WRITE_TRUNCATED_RESPONSE:
- DCHECK_EQ(OK, rv);
- rv = DoCacheWriteTruncatedResponse();
- break;
- case STATE_CACHE_WRITE_RESPONSE_COMPLETE:
- rv = DoCacheWriteResponseComplete(rv);
- break;
case STATE_CACHE_READ_METADATA:
DCHECK_EQ(OK, rv);
rv = DoCacheReadMetadata();
@@ -926,12 +922,12 @@ int HttpCache::Transaction::DoLoop(int result) {
case STATE_CACHE_READ_METADATA_COMPLETE:
rv = DoCacheReadMetadataComplete(rv);
break;
- case STATE_CACHE_QUERY_DATA:
+ case STATE_NETWORK_READ:
DCHECK_EQ(OK, rv);
- rv = DoCacheQueryData();
+ rv = DoNetworkRead();
break;
- case STATE_CACHE_QUERY_DATA_COMPLETE:
- rv = DoCacheQueryDataComplete(rv);
+ case STATE_NETWORK_READ_COMPLETE:
+ rv = DoNetworkReadComplete(rv);
break;
case STATE_CACHE_READ_DATA:
DCHECK_EQ(OK, rv);
@@ -946,6 +942,13 @@ int HttpCache::Transaction::DoLoop(int result) {
case STATE_CACHE_WRITE_DATA_COMPLETE:
rv = DoCacheWriteDataComplete(rv);
break;
+ case STATE_CACHE_WRITE_TRUNCATED_RESPONSE:
+ DCHECK_EQ(OK, rv);
+ rv = DoCacheWriteTruncatedResponse();
+ break;
+ case STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE:
+ rv = DoCacheWriteTruncatedResponseComplete(rv);
+ break;
default:
NOTREACHED() << "bad state";
rv = ERR_FAILED;
@@ -953,8 +956,10 @@ int HttpCache::Transaction::DoLoop(int result) {
}
} while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
- if (rv != ERR_IO_PENDING)
- HandleResult(rv);
+ if (rv != ERR_IO_PENDING && !callback_.is_null()) {
+ read_buf_ = NULL; // Release the buffer before invoking the callback.
+ base::ResetAndReturn(&callback_).Run(rv);
+ }
return rv;
}
@@ -1016,7 +1021,7 @@ int HttpCache::Transaction::DoGetBackendComplete(int result) {
return ERR_CACHE_MISS;
if (mode_ == NONE) {
- if (partial_.get()) {
+ if (partial_) {
partial_->RestoreHeaders(&custom_request_->extra_headers);
partial_.reset();
}
@@ -1031,192 +1036,6 @@ int HttpCache::Transaction::DoGetBackendComplete(int result) {
return OK;
}
-int HttpCache::Transaction::DoSendRequest() {
- DCHECK(mode_ & WRITE || mode_ == NONE);
- DCHECK(!network_trans_.get());
-
- send_request_since_ = TimeTicks::Now();
-
- // Create a network transaction.
- int rv = cache_->network_layer_->CreateTransaction(priority_,
- &network_trans_);
- if (rv != OK)
- return rv;
- network_trans_->SetBeforeNetworkStartCallback(before_network_start_callback_);
- network_trans_->SetBeforeProxyHeadersSentCallback(
- before_proxy_headers_sent_callback_);
-
- // Old load timing information, if any, is now obsolete.
- old_network_trans_load_timing_.reset();
-
- if (websocket_handshake_stream_base_create_helper_)
- network_trans_->SetWebSocketHandshakeStreamCreateHelper(
- websocket_handshake_stream_base_create_helper_);
-
- next_state_ = STATE_SEND_REQUEST_COMPLETE;
- rv = network_trans_->Start(request_, io_callback_, net_log_);
- return rv;
-}
-
-int HttpCache::Transaction::DoSendRequestComplete(int result) {
- if (!cache_.get())
- return ERR_UNEXPECTED;
-
- // If we tried to conditionalize the request and failed, we know
- // we won't be reading from the cache after this point.
- if (couldnt_conditionalize_request_)
- mode_ = WRITE;
-
- if (result == OK) {
- next_state_ = STATE_SUCCESSFUL_SEND_REQUEST;
- return OK;
- }
-
- const HttpResponseInfo* response = network_trans_->GetResponseInfo();
- response_.network_accessed = response->network_accessed;
-
- // Do not record requests that have network errors or restarts.
- UpdateTransactionPattern(PATTERN_NOT_COVERED);
- if (IsCertificateError(result)) {
- // If we get a certificate error, then there is a certificate in ssl_info,
- // so GetResponseInfo() should never return NULL here.
- DCHECK(response);
- response_.ssl_info = response->ssl_info;
- } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
- DCHECK(response);
- response_.cert_request_info = response->cert_request_info;
- } else if (response_.was_cached) {
- DoneWritingToEntry(true);
- }
-
- return result;
-}
-
-// We received the response headers and there is no error.
-int HttpCache::Transaction::DoSuccessfulSendRequest() {
- DCHECK(!new_response_);
- const HttpResponseInfo* new_response = network_trans_->GetResponseInfo();
-
- if (new_response->headers->response_code() == 401 ||
- new_response->headers->response_code() == 407) {
- auth_response_ = *new_response;
- if (!reading_)
- return OK;
-
- // We initiated a second request the caller doesn't know about. We should be
- // able to authenticate this request because we should have authenticated
- // this URL moments ago.
- if (IsReadyToRestartForAuth()) {
- DCHECK(!response_.auth_challenge.get());
- next_state_ = STATE_SEND_REQUEST_COMPLETE;
- // In theory we should check to see if there are new cookies, but there
- // is no way to do that from here.
- return network_trans_->RestartWithAuth(AuthCredentials(), io_callback_);
- }
-
- // We have to perform cleanup at this point so that at least the next
- // request can succeed. We do not retry at this point, because data
- // has been read and we have no way to gather credentials. We would
- // fail again, and potentially loop. This can happen if the credentials
- // expire while chrome is suspended.
- if (entry_)
- DoomPartialEntry(false);
- mode_ = NONE;
- partial_.reset();
- ResetNetworkTransaction();
- return ERR_CACHE_AUTH_FAILURE_AFTER_READ;
- }
-
- new_response_ = new_response;
- if (!ValidatePartialResponse() && !auth_response_.headers.get()) {
- // Something went wrong with this request and we have to restart it.
- // If we have an authentication response, we are exposed to weird things
- // hapenning if the user cancels the authentication before we receive
- // the new response.
- net_log_.AddEvent(NetLog::TYPE_HTTP_CACHE_RE_SEND_PARTIAL_REQUEST);
- UpdateTransactionPattern(PATTERN_NOT_COVERED);
- response_ = HttpResponseInfo();
- ResetNetworkTransaction();
- new_response_ = NULL;
- next_state_ = STATE_SEND_REQUEST;
- return OK;
- }
-
- if (handling_206_ && mode_ == READ_WRITE && !truncated_ && !is_sparse_) {
- // We have stored the full entry, but it changed and the server is
- // sending a range. We have to delete the old entry.
- UpdateTransactionPattern(PATTERN_NOT_COVERED);
- DoneWritingToEntry(false);
- }
-
- if (mode_ == WRITE &&
- transaction_pattern_ != PATTERN_ENTRY_CANT_CONDITIONALIZE) {
- UpdateTransactionPattern(PATTERN_ENTRY_NOT_CACHED);
- }
-
- // Invalidate any cached GET with a successful PUT or DELETE.
- if (mode_ == WRITE &&
- (request_->method == "PUT" || request_->method == "DELETE")) {
- if (NonErrorResponse(new_response->headers->response_code())) {
- int ret = cache_->DoomEntry(cache_key_, NULL);
- DCHECK_EQ(OK, ret);
- }
- cache_->DoneWritingToEntry(entry_, true);
- entry_ = NULL;
- mode_ = NONE;
- }
-
- // Invalidate any cached GET with a successful POST.
- if (!(effective_load_flags_ & LOAD_DISABLE_CACHE) &&
- request_->method == "POST" &&
- NonErrorResponse(new_response->headers->response_code())) {
- cache_->DoomMainEntryForUrl(request_->url);
- }
-
- RecordNoStoreHeaderHistogram(request_->load_flags, new_response);
-
- if (new_response_->headers->response_code() == 416 &&
- (request_->method == "GET" || request_->method == "POST")) {
- // If there is an active entry it may be destroyed with this transaction.
- response_ = *new_response_;
- return OK;
- }
-
- // Are we expecting a response to a conditional query?
- if (mode_ == READ_WRITE || mode_ == UPDATE) {
- if (new_response->headers->response_code() == 304 || handling_206_) {
- UpdateTransactionPattern(PATTERN_ENTRY_VALIDATED);
- next_state_ = STATE_UPDATE_CACHED_RESPONSE;
- return OK;
- }
- UpdateTransactionPattern(PATTERN_ENTRY_UPDATED);
- mode_ = WRITE;
- }
-
- next_state_ = STATE_OVERWRITE_CACHED_RESPONSE;
- return OK;
-}
-
-int HttpCache::Transaction::DoNetworkRead() {
- next_state_ = STATE_NETWORK_READ_COMPLETE;
- return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_);
-}
-
-int HttpCache::Transaction::DoNetworkReadComplete(int result) {
- DCHECK(mode_ & WRITE || mode_ == NONE);
-
- if (!cache_.get())
- return ERR_UNEXPECTED;
-
- // If there is an error or we aren't saving the data, we are done; just wait
- // until the destructor runs to see if we can keep the data.
- if (mode_ == NONE || result < 0)
- return result;
-
- next_state_ = STATE_CACHE_WRITE_DATA;
- return result;
-}
-
int HttpCache::Transaction::DoInitEntry() {
DCHECK(!new_entry_);
@@ -1282,6 +1101,24 @@ int HttpCache::Transaction::DoOpenEntryComplete(int result) {
return ERR_CACHE_MISS;
}
+int HttpCache::Transaction::DoDoomEntry() {
+ next_state_ = STATE_DOOM_ENTRY_COMPLETE;
+ cache_pending_ = true;
+ if (first_cache_access_since_.is_null())
+ first_cache_access_since_ = TimeTicks::Now();
+ net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY);
+ return cache_->DoomEntry(cache_key_, this);
+}
+
+int HttpCache::Transaction::DoDoomEntryComplete(int result) {
+ net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY, result);
+ next_state_ = STATE_CREATE_ENTRY;
+ cache_pending_ = false;
+ if (result == ERR_CACHE_RACE)
+ next_state_ = STATE_INIT_ENTRY;
+ return OK;
+}
+
int HttpCache::Transaction::DoCreateEntry() {
DCHECK(!new_entry_);
next_state_ = STATE_CREATE_ENTRY_COMPLETE;
@@ -1297,45 +1134,29 @@ int HttpCache::Transaction::DoCreateEntryComplete(int result) {
net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY,
result);
cache_pending_ = false;
- next_state_ = STATE_ADD_TO_ENTRY;
+ switch (result) {
+ case OK:
+ next_state_ = STATE_ADD_TO_ENTRY;
+ break;
- if (result == ERR_CACHE_RACE) {
- next_state_ = STATE_INIT_ENTRY;
- return OK;
- }
+ case ERR_CACHE_RACE:
+ next_state_ = STATE_INIT_ENTRY;
+ break;
- if (result != OK) {
- // We have a race here: Maybe we failed to open the entry and decided to
- // create one, but by the time we called create, another transaction already
- // created the entry. If we want to eliminate this issue, we need an atomic
- // OpenOrCreate() method exposed by the disk cache.
- DLOG(WARNING) << "Unable to create cache entry";
- mode_ = NONE;
- if (partial_.get())
- partial_->RestoreHeaders(&custom_request_->extra_headers);
- next_state_ = STATE_SEND_REQUEST;
+ default:
+ // We have a race here: Maybe we failed to open the entry and decided to
+ // create one, but by the time we called create, another transaction
+ // already created the entry. If we want to eliminate this issue, we
+ // need an atomic OpenOrCreate() method exposed by the disk cache.
+ DLOG(WARNING) << "Unable to create cache entry";
+ mode_ = NONE;
+ if (partial_)
+ partial_->RestoreHeaders(&custom_request_->extra_headers);
+ next_state_ = STATE_SEND_REQUEST;
}
return OK;
}
-int HttpCache::Transaction::DoDoomEntry() {
- next_state_ = STATE_DOOM_ENTRY_COMPLETE;
- cache_pending_ = true;
- if (first_cache_access_since_.is_null())
- first_cache_access_since_ = TimeTicks::Now();
- net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY);
- return cache_->DoomEntry(cache_key_, this);
-}
-
-int HttpCache::Transaction::DoDoomEntryComplete(int result) {
- net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY, result);
- next_state_ = STATE_CREATE_ENTRY;
- cache_pending_ = false;
- if (result == ERR_CACHE_RACE)
- next_state_ = STATE_INIT_ENTRY;
- return OK;
-}
-
int HttpCache::Transaction::DoAddToEntry() {
DCHECK(new_entry_);
cache_pending_ = true;
@@ -1416,7 +1237,7 @@ int HttpCache::Transaction::DoAddToEntryComplete(int result) {
}
if (mode_ == WRITE) {
- if (partial_.get())
+ if (partial_)
partial_->RestoreHeaders(&custom_request_->extra_headers);
next_state_ = STATE_SEND_REQUEST;
} else {
@@ -1427,6 +1248,121 @@ int HttpCache::Transaction::DoAddToEntryComplete(int result) {
return OK;
}
+int HttpCache::Transaction::DoCacheReadResponse() {
+ DCHECK(entry_);
+ next_state_ = STATE_CACHE_READ_RESPONSE_COMPLETE;
+
+ io_buf_len_ = entry_->disk_entry->GetDataSize(kResponseInfoIndex);
+ read_buf_ = new IOBuffer(io_buf_len_);
+
+ net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_INFO);
+ return entry_->disk_entry->ReadData(kResponseInfoIndex, 0, read_buf_.get(),
+ io_buf_len_, io_callback_);
+}
+
+int HttpCache::Transaction::DoCacheReadResponseComplete(int result) {
+ net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result);
+ if (result != io_buf_len_ ||
+ !HttpCache::ParseResponseInfo(read_buf_->data(), io_buf_len_, &response_,
+ &truncated_)) {
+ return OnCacheReadError(result, true);
+ }
+
+ // cert_cache() will be null if the CertCacheTrial field trial is disabled.
+ if (cache_->cert_cache() && response_.ssl_info.is_valid())
+ ReadCertChain();
+
+ // Some resources may have slipped in as truncated when they're not.
+ int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex);
+ if (response_.headers->GetContentLength() == current_size)
+ truncated_ = false;
+
+ if ((response_.unused_since_prefetch &&
+ !(request_->load_flags & LOAD_PREFETCH)) ||
+ (!response_.unused_since_prefetch &&
+ (request_->load_flags & LOAD_PREFETCH))) {
+ // Either this is the first use of an entry since it was prefetched or
+ // this is a prefetch. The value of response.unused_since_prefetch is valid
+ // for this transaction but the bit needs to be flipped in storage.
+ next_state_ = STATE_TOGGLE_UNUSED_SINCE_PREFETCH;
+ return OK;
+ }
+
+ next_state_ = STATE_CACHE_DISPATCH_VALIDATION;
+ return OK;
+}
+
+int HttpCache::Transaction::DoCacheToggleUnusedSincePrefetch() {
+ // Write back the toggled value for the next use of this entry.
+ response_.unused_since_prefetch = !response_.unused_since_prefetch;
+
+ // TODO(jkarlin): If DoUpdateCachedResponse is also called for this
+ // transaction then metadata will be written to cache twice. If prefetching
+ // becomes more common, consider combining the writes.
+
+ // TODO(rtenneti): Remove ScopedTracker below once crbug.com/422516 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "422516 HttpCache::Transaction::DoCacheToggleUnusedSincePrefetch"));
+
+ next_state_ = STATE_TOGGLE_UNUSED_SINCE_PREFETCH_COMPLETE;
+ return WriteResponseInfoToEntry(false);
+}
+
+int HttpCache::Transaction::DoCacheToggleUnusedSincePrefetchComplete(
+ int result) {
+ // Restore the original value for this transaction.
+ response_.unused_since_prefetch = !response_.unused_since_prefetch;
+ next_state_ = STATE_CACHE_DISPATCH_VALIDATION;
+ return OnWriteResponseInfoToEntryComplete(result);
+}
+
+int HttpCache::Transaction::DoCacheDispatchValidation() {
+ // We now have access to the cache entry.
+ //
+ // o if we are a reader for the transaction, then we can start reading the
+ // cache entry.
+ //
+ // o if we can read or write, then we should check if the cache entry needs
+ // to be validated and then issue a network request if needed or just read
+ // from the cache if the cache entry is already valid.
+ //
+ // o if we are set to UPDATE, then we are handling an externally
+ // conditionalized request (if-modified-since / if-none-match). We check
+ // if the request headers define a validation request.
+ //
+ int result = ERR_FAILED;
+ switch (mode_) {
+ case READ:
+ UpdateTransactionPattern(PATTERN_ENTRY_USED);
+ result = BeginCacheRead();
+ break;
+ case READ_WRITE:
+ result = BeginPartialCacheValidation();
+ break;
+ case UPDATE:
+ result = BeginExternallyConditionalizedRequest();
+ break;
+ case WRITE:
+ default:
+ NOTREACHED();
+ }
+ return result;
+}
+
+int HttpCache::Transaction::DoCacheQueryData() {
+ next_state_ = STATE_CACHE_QUERY_DATA_COMPLETE;
+ return entry_->disk_entry->ReadyForSparseIO(io_callback_);
+}
+
+int HttpCache::Transaction::DoCacheQueryDataComplete(int result) {
+ DCHECK_EQ(OK, result);
+ if (!cache_.get())
+ return ERR_UNEXPECTED;
+
+ return ValidateEntryHeadersAndContinue();
+}
+
// We may end up here multiple times for a given request.
int HttpCache::Transaction::DoStartPartialCacheValidation() {
if (mode_ == NONE)
@@ -1462,6 +1398,173 @@ int HttpCache::Transaction::DoCompletePartialCacheValidation(int result) {
return BeginCacheValidation();
}
+int HttpCache::Transaction::DoSendRequest() {
+ DCHECK(mode_ & WRITE || mode_ == NONE);
+ DCHECK(!network_trans_.get());
+
+ send_request_since_ = TimeTicks::Now();
+
+ // Create a network transaction.
+ int rv =
+ cache_->network_layer_->CreateTransaction(priority_, &network_trans_);
+ if (rv != OK)
+ return rv;
+ network_trans_->SetBeforeNetworkStartCallback(before_network_start_callback_);
+ network_trans_->SetBeforeProxyHeadersSentCallback(
+ before_proxy_headers_sent_callback_);
+
+ // Old load timing information, if any, is now obsolete.
+ old_network_trans_load_timing_.reset();
+ old_remote_endpoint_ = IPEndPoint();
+
+ if (websocket_handshake_stream_base_create_helper_)
+ network_trans_->SetWebSocketHandshakeStreamCreateHelper(
+ websocket_handshake_stream_base_create_helper_);
+
+ next_state_ = STATE_SEND_REQUEST_COMPLETE;
+ rv = network_trans_->Start(request_, io_callback_, net_log_);
+ return rv;
+}
+
+int HttpCache::Transaction::DoSendRequestComplete(int result) {
+ if (!cache_.get())
+ return ERR_UNEXPECTED;
+
+ // If we tried to conditionalize the request and failed, we know
+ // we won't be reading from the cache after this point.
+ if (couldnt_conditionalize_request_)
+ mode_ = WRITE;
+
+ if (result == OK) {
+ next_state_ = STATE_SUCCESSFUL_SEND_REQUEST;
+ return OK;
+ }
+
+ const HttpResponseInfo* response = network_trans_->GetResponseInfo();
+ response_.network_accessed = response->network_accessed;
+
+ // Do not record requests that have network errors or restarts.
+ UpdateTransactionPattern(PATTERN_NOT_COVERED);
+ if (IsCertificateError(result)) {
+ // If we get a certificate error, then there is a certificate in ssl_info,
+ // so GetResponseInfo() should never return NULL here.
+ DCHECK(response);
+ response_.ssl_info = response->ssl_info;
+ } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
+ DCHECK(response);
+ response_.cert_request_info = response->cert_request_info;
+ } else if (response_.was_cached) {
+ DoneWritingToEntry(true);
+ }
+
+ return result;
+}
+
+// We received the response headers and there is no error.
+int HttpCache::Transaction::DoSuccessfulSendRequest() {
+ DCHECK(!new_response_);
+ const HttpResponseInfo* new_response = network_trans_->GetResponseInfo();
+
+ if (new_response->headers->response_code() == 401 ||
+ new_response->headers->response_code() == 407) {
+ auth_response_ = *new_response;
+ if (!reading_)
+ return OK;
+
+ // We initiated a second request the caller doesn't know about. We should be
+ // able to authenticate this request because we should have authenticated
+ // this URL moments ago.
+ if (IsReadyToRestartForAuth()) {
+ DCHECK(!response_.auth_challenge.get());
+ next_state_ = STATE_SEND_REQUEST_COMPLETE;
+ // In theory we should check to see if there are new cookies, but there
+ // is no way to do that from here.
+ return network_trans_->RestartWithAuth(AuthCredentials(), io_callback_);
+ }
+
+ // We have to perform cleanup at this point so that at least the next
+ // request can succeed. We do not retry at this point, because data
+ // has been read and we have no way to gather credentials. We would
+ // fail again, and potentially loop. This can happen if the credentials
+ // expire while chrome is suspended.
+ if (entry_)
+ DoomPartialEntry(false);
+ mode_ = NONE;
+ partial_.reset();
+ ResetNetworkTransaction();
+ return ERR_CACHE_AUTH_FAILURE_AFTER_READ;
+ }
+
+ new_response_ = new_response;
+ if (!ValidatePartialResponse() && !auth_response_.headers.get()) {
+ // Something went wrong with this request and we have to restart it.
+ // If we have an authentication response, we are exposed to weird things
+ // hapenning if the user cancels the authentication before we receive
+ // the new response.
+ net_log_.AddEvent(NetLog::TYPE_HTTP_CACHE_RE_SEND_PARTIAL_REQUEST);
+ UpdateTransactionPattern(PATTERN_NOT_COVERED);
+ response_ = HttpResponseInfo();
+ ResetNetworkTransaction();
+ new_response_ = NULL;
+ next_state_ = STATE_SEND_REQUEST;
+ return OK;
+ }
+
+ if (handling_206_ && mode_ == READ_WRITE && !truncated_ && !is_sparse_) {
+ // We have stored the full entry, but it changed and the server is
+ // sending a range. We have to delete the old entry.
+ UpdateTransactionPattern(PATTERN_NOT_COVERED);
+ DoneWritingToEntry(false);
+ }
+
+ if (mode_ == WRITE &&
+ transaction_pattern_ != PATTERN_ENTRY_CANT_CONDITIONALIZE) {
+ UpdateTransactionPattern(PATTERN_ENTRY_NOT_CACHED);
+ }
+
+ // Invalidate any cached GET with a successful PUT or DELETE.
+ if (mode_ == WRITE &&
+ (request_->method == "PUT" || request_->method == "DELETE")) {
+ if (NonErrorResponse(new_response->headers->response_code())) {
+ int ret = cache_->DoomEntry(cache_key_, NULL);
+ DCHECK_EQ(OK, ret);
+ }
+ cache_->DoneWritingToEntry(entry_, true);
+ entry_ = NULL;
+ mode_ = NONE;
+ }
+
+ // Invalidate any cached GET with a successful POST.
+ if (!(effective_load_flags_ & LOAD_DISABLE_CACHE) &&
+ request_->method == "POST" &&
+ NonErrorResponse(new_response->headers->response_code())) {
+ cache_->DoomMainEntryForUrl(request_->url);
+ }
+
+ RecordNoStoreHeaderHistogram(request_->load_flags, new_response);
+
+ if (new_response_->headers->response_code() == 416 &&
+ (request_->method == "GET" || request_->method == "POST")) {
+ // If there is an active entry it may be destroyed with this transaction.
+ response_ = *new_response_;
+ return OK;
+ }
+
+ // Are we expecting a response to a conditional query?
+ if (mode_ == READ_WRITE || mode_ == UPDATE) {
+ if (new_response->headers->response_code() == 304 || handling_206_) {
+ UpdateTransactionPattern(PATTERN_ENTRY_VALIDATED);
+ next_state_ = STATE_UPDATE_CACHED_RESPONSE;
+ return OK;
+ }
+ UpdateTransactionPattern(PATTERN_ENTRY_UPDATED);
+ mode_ = WRITE;
+ }
+
+ next_state_ = STATE_OVERWRITE_CACHED_RESPONSE;
+ return OK;
+}
+
// We received 304 or 206 and we want to update the cached response headers.
int HttpCache::Transaction::DoUpdateCachedResponse() {
next_state_ = STATE_UPDATE_CACHED_RESPONSE_COMPLETE;
@@ -1493,14 +1596,28 @@ int HttpCache::Transaction::DoUpdateCachedResponse() {
// If we are already reading, we already updated the headers for this
// request; doing it again will change Content-Length.
if (!reading_) {
- target_state_ = STATE_UPDATE_CACHED_RESPONSE_COMPLETE;
- next_state_ = STATE_CACHE_WRITE_RESPONSE;
+ next_state_ = STATE_CACHE_WRITE_UPDATED_RESPONSE;
rv = OK;
}
}
return rv;
}
+int HttpCache::Transaction::DoCacheWriteUpdatedResponse() {
+ // TODO(rtenneti): Remove ScopedTracker below once crbug.com/422516 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "422516 HttpCache::Transaction::DoCacheWriteUpdatedResponse"));
+
+ next_state_ = STATE_CACHE_WRITE_UPDATED_RESPONSE_COMPLETE;
+ return WriteResponseInfoToEntry(false);
+}
+
+int HttpCache::Transaction::DoCacheWriteUpdatedResponseComplete(int result) {
+ next_state_ = STATE_UPDATE_CACHED_RESPONSE_COMPLETE;
+ return OnWriteResponseInfoToEntryComplete(result);
+}
+
int HttpCache::Transaction::DoUpdateCachedResponseComplete(int result) {
if (mode_ == UPDATE) {
DCHECK(!handling_206_);
@@ -1512,7 +1629,7 @@ int HttpCache::Transaction::DoUpdateCachedResponseComplete(int result) {
DoneWritingToEntry(true);
} else if (entry_ && !handling_206_) {
DCHECK_EQ(READ_WRITE, mode_);
- if (!partial_.get() || partial_->IsLastRange()) {
+ if (!partial_ || partial_->IsLastRange()) {
cache_->ConvertWriterToReader(entry_);
mode_ = READ;
}
@@ -1541,7 +1658,7 @@ int HttpCache::Transaction::DoOverwriteCachedResponse() {
}
// We change the value of Content-Length for partial content.
- if (handling_206_ && partial_.get())
+ if (handling_206_ && partial_)
partial_->FixContentLength(new_response_->headers.get());
response_ = *new_response_;
@@ -1558,18 +1675,31 @@ int HttpCache::Transaction::DoOverwriteCachedResponse() {
// There is no point in storing this resource because it will never be used.
// This may change if we support LOAD_ONLY_FROM_CACHE with sparse entries.
DoneWritingToEntry(false);
- if (partial_.get())
+ if (partial_)
partial_->FixResponseHeaders(response_.headers.get(), true);
next_state_ = STATE_PARTIAL_HEADERS_RECEIVED;
return OK;
}
- target_state_ = STATE_TRUNCATE_CACHED_DATA;
- next_state_ = truncated_ ? STATE_CACHE_WRITE_TRUNCATED_RESPONSE :
- STATE_CACHE_WRITE_RESPONSE;
+ next_state_ = STATE_CACHE_WRITE_RESPONSE;
return OK;
}
+int HttpCache::Transaction::DoCacheWriteResponse() {
+ // TODO(rtenneti): Remove ScopedTracker below once crbug.com/422516 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "422516 HttpCache::Transaction::DoCacheWriteResponse"));
+
+ next_state_ = STATE_CACHE_WRITE_RESPONSE_COMPLETE;
+ return WriteResponseInfoToEntry(truncated_);
+}
+
+int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) {
+ next_state_ = STATE_TRUNCATE_CACHED_DATA;
+ return OnWriteResponseInfoToEntryComplete(result);
+}
+
int HttpCache::Transaction::DoTruncateCachedData() {
next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE;
if (!entry_)
@@ -1616,11 +1746,10 @@ int HttpCache::Transaction::DoTruncateCachedMetadataComplete(int result) {
int HttpCache::Transaction::DoPartialHeadersReceived() {
new_response_ = NULL;
- if (entry_ && !partial_.get() &&
- entry_->disk_entry->GetDataSize(kMetadataIndex))
+ if (entry_ && !partial_ && entry_->disk_entry->GetDataSize(kMetadataIndex))
next_state_ = STATE_CACHE_READ_METADATA;
- if (!partial_.get())
+ if (!partial_)
return OK;
if (reading_) {
@@ -1637,142 +1766,6 @@ int HttpCache::Transaction::DoPartialHeadersReceived() {
return OK;
}
-int HttpCache::Transaction::DoCacheReadResponse() {
- DCHECK(entry_);
- next_state_ = STATE_CACHE_READ_RESPONSE_COMPLETE;
-
- io_buf_len_ = entry_->disk_entry->GetDataSize(kResponseInfoIndex);
- read_buf_ = new IOBuffer(io_buf_len_);
-
- net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_INFO);
- return entry_->disk_entry->ReadData(kResponseInfoIndex, 0, read_buf_.get(),
- io_buf_len_, io_callback_);
-}
-
-int HttpCache::Transaction::DoCacheReadResponseComplete(int result) {
- net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result);
- if (result != io_buf_len_ ||
- !HttpCache::ParseResponseInfo(read_buf_->data(), io_buf_len_,
- &response_, &truncated_)) {
- return OnCacheReadError(result, true);
- }
-
- // cert_cache() will be null if the CertCacheTrial field trial is disabled.
- if (cache_->cert_cache() && response_.ssl_info.is_valid())
- ReadCertChain();
-
- // Some resources may have slipped in as truncated when they're not.
- int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex);
- if (response_.headers->GetContentLength() == current_size)
- truncated_ = false;
-
- if ((response_.unused_since_prefetch &&
- !(request_->load_flags & LOAD_PREFETCH)) ||
- (!response_.unused_since_prefetch &&
- (request_->load_flags & LOAD_PREFETCH))) {
- // Either this is the first use of an entry since it was prefetched or
- // this is a prefetch. The value of response.unused_since_prefetch is valid
- // for this transaction but the bit needs to be flipped in storage.
- next_state_ = STATE_TOGGLE_UNUSED_SINCE_PREFETCH;
- return OK;
- }
-
- next_state_ = STATE_CACHE_DISPATCH_VALIDATION;
- return OK;
-}
-
-int HttpCache::Transaction::DoCacheDispatchValidation() {
- // We now have access to the cache entry.
- //
- // o if we are a reader for the transaction, then we can start reading the
- // cache entry.
- //
- // o if we can read or write, then we should check if the cache entry needs
- // to be validated and then issue a network request if needed or just read
- // from the cache if the cache entry is already valid.
- //
- // o if we are set to UPDATE, then we are handling an externally
- // conditionalized request (if-modified-since / if-none-match). We check
- // if the request headers define a validation request.
- //
- int result = ERR_FAILED;
- switch (mode_) {
- case READ:
- UpdateTransactionPattern(PATTERN_ENTRY_USED);
- result = BeginCacheRead();
- break;
- case READ_WRITE:
- result = BeginPartialCacheValidation();
- break;
- case UPDATE:
- result = BeginExternallyConditionalizedRequest();
- break;
- case WRITE:
- default:
- NOTREACHED();
- }
- return result;
-}
-
-int HttpCache::Transaction::DoCacheToggleUnusedSincePrefetch() {
- // Write back the toggled value for the next use of this entry.
- response_.unused_since_prefetch = !response_.unused_since_prefetch;
-
- // TODO(jkarlin): If DoUpdateCachedResponse is also called for this
- // transaction then metadata will be written to cache twice. If prefetching
- // becomes more common, consider combining the writes.
- target_state_ = STATE_TOGGLE_UNUSED_SINCE_PREFETCH_COMPLETE;
- next_state_ = STATE_CACHE_WRITE_RESPONSE;
- return OK;
-}
-
-int HttpCache::Transaction::DoCacheToggleUnusedSincePrefetchComplete(
- int result) {
- // Restore the original value for this transaction.
- response_.unused_since_prefetch = !response_.unused_since_prefetch;
- next_state_ = STATE_CACHE_DISPATCH_VALIDATION;
- return OK;
-}
-
-int HttpCache::Transaction::DoCacheWriteResponse() {
- // TODO(rtenneti): Remove ScopedTracker below once crbug.com/422516 is fixed.
- tracked_objects::ScopedTracker tracking_profile(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "422516 HttpCache::Transaction::DoCacheWriteResponse"));
-
- if (entry_) {
- if (net_log_.IsCapturing())
- net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_WRITE_INFO);
- }
- return WriteResponseInfoToEntry(false);
-}
-
-int HttpCache::Transaction::DoCacheWriteTruncatedResponse() {
- if (entry_) {
- if (net_log_.IsCapturing())
- net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_WRITE_INFO);
- }
- return WriteResponseInfoToEntry(true);
-}
-
-int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) {
- next_state_ = target_state_;
- target_state_ = STATE_NONE;
- if (!entry_)
- return OK;
- if (net_log_.IsCapturing()) {
- net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_WRITE_INFO,
- result);
- }
-
- // Balance the AddRef from WriteResponseInfoToEntry.
- if (result != io_buf_len_) {
- DLOG(ERROR) << "failed to write response info to cache";
- DoneWritingToEntry(false);
- }
- return OK;
-}
-
int HttpCache::Transaction::DoCacheReadMetadata() {
DCHECK(entry_);
DCHECK(!response_.metadata.get());
@@ -1795,26 +1788,36 @@ int HttpCache::Transaction::DoCacheReadMetadataComplete(int result) {
return OK;
}
-int HttpCache::Transaction::DoCacheQueryData() {
- next_state_ = STATE_CACHE_QUERY_DATA_COMPLETE;
- return entry_->disk_entry->ReadyForSparseIO(io_callback_);
+int HttpCache::Transaction::DoNetworkRead() {
+ next_state_ = STATE_NETWORK_READ_COMPLETE;
+ return network_trans_->Read(read_buf_.get(), io_buf_len_, io_callback_);
}
-int HttpCache::Transaction::DoCacheQueryDataComplete(int result) {
- DCHECK_EQ(OK, result);
+int HttpCache::Transaction::DoNetworkReadComplete(int result) {
+ DCHECK(mode_ & WRITE || mode_ == NONE);
+
if (!cache_.get())
return ERR_UNEXPECTED;
- return ValidateEntryHeadersAndContinue();
+ // If there is an error or we aren't saving the data, we are done; just wait
+ // until the destructor runs to see if we can keep the data.
+ if (mode_ == NONE || result < 0)
+ return result;
+
+ next_state_ = STATE_CACHE_WRITE_DATA;
+ return result;
}
int HttpCache::Transaction::DoCacheReadData() {
+ if (request_->method == "HEAD")
+ return 0;
+
DCHECK(entry_);
next_state_ = STATE_CACHE_READ_DATA_COMPLETE;
if (net_log_.IsCapturing())
net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_DATA);
- if (partial_.get()) {
+ if (partial_) {
return partial_->CacheRead(entry_->disk_entry, read_buf_.get(), io_buf_len_,
io_callback_);
}
@@ -1833,7 +1836,7 @@ int HttpCache::Transaction::DoCacheReadDataComplete(int result) {
if (!cache_.get())
return ERR_UNEXPECTED;
- if (partial_.get()) {
+ if (partial_) {
// Partial requests are confusing to report in histograms because they may
// have multiple underlying requests.
UpdateTransactionPattern(PATTERN_NOT_COVERED);
@@ -1875,7 +1878,6 @@ int HttpCache::Transaction::DoCacheWriteDataComplete(int result) {
result);
}
}
- // Balance the AddRef from DoCacheWriteData.
if (!cache_.get())
return ERR_UNEXPECTED;
@@ -1886,31 +1888,42 @@ int HttpCache::Transaction::DoCacheWriteDataComplete(int result) {
// We want to ignore errors writing to disk and just keep reading from
// the network.
result = write_len_;
- } else if (!done_reading_ && entry_) {
+ } else if (!done_reading_ && entry_ && (!partial_ || truncated_)) {
int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex);
int64 body_size = response_.headers->GetContentLength();
if (body_size >= 0 && body_size <= current_size)
done_reading_ = true;
}
- if (partial_.get()) {
+ if (partial_) {
// This may be the last request.
- if (!(result == 0 && !truncated_ &&
- (partial_->IsLastRange() || mode_ == WRITE)))
+ if (result != 0 || truncated_ ||
+ !(partial_->IsLastRange() || mode_ == WRITE)) {
return DoPartialNetworkReadCompleted(result);
+ }
}
if (result == 0) {
// End of file. This may be the result of a connection problem so see if we
// have to keep the entry around to be flagged as truncated later on.
- if (done_reading_ || !entry_ || partial_.get() ||
- response_.headers->GetContentLength() <= 0)
+ if (done_reading_ || !entry_ || partial_ ||
+ response_.headers->GetContentLength() <= 0) {
DoneWritingToEntry(true);
+ }
}
return result;
}
+int HttpCache::Transaction::DoCacheWriteTruncatedResponse() {
+ next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE;
+ return WriteResponseInfoToEntry(true);
+}
+
+int HttpCache::Transaction::DoCacheWriteTruncatedResponseComplete(int result) {
+ return OnWriteResponseInfoToEntryComplete(result);
+}
+
//-----------------------------------------------------------------------------
void HttpCache::Transaction::ReadCertChain() {
@@ -2098,7 +2111,7 @@ bool HttpCache::Transaction::ShouldPassThrough() {
int HttpCache::Transaction::BeginCacheRead() {
// We don't support any combination of LOAD_ONLY_FROM_CACHE and byte ranges.
- if (response_.headers->response_code() == 206 || partial_.get()) {
+ if (response_.headers->response_code() == 206 || partial_) {
NOTREACHED();
return ERR_CACHE_MISS;
}
@@ -2117,12 +2130,19 @@ int HttpCache::Transaction::BeginCacheRead() {
}
int HttpCache::Transaction::BeginCacheValidation() {
- DCHECK(mode_ == READ_WRITE);
+ DCHECK_EQ(mode_, READ_WRITE);
ValidationType required_validation = RequiresValidation();
bool skip_validation = (required_validation == VALIDATION_NONE);
+ if ((effective_load_flags_ & LOAD_SUPPORT_ASYNC_REVALIDATION) &&
+ required_validation == VALIDATION_ASYNCHRONOUS) {
+ DCHECK_EQ(request_->method, "GET");
+ skip_validation = true;
+ response_.async_revalidation_required = true;
+ }
+
if (request_->method == "HEAD" &&
(truncated_ || response_.headers->response_code() == 206)) {
DCHECK(!partial_);
@@ -2142,7 +2162,7 @@ int HttpCache::Transaction::BeginCacheValidation() {
skip_validation = !partial_->initial_validation();
}
- if (partial_.get() && (is_sparse_ || truncated_) &&
+ if (partial_ && (is_sparse_ || truncated_) &&
(!partial_->IsCurrentRangeCached() || invalid_range_)) {
// Force revalidation for sparse or truncated entries. Note that we don't
// want to ignore the regular validation logic just because a byte range was
@@ -2163,7 +2183,7 @@ int HttpCache::Transaction::BeginCacheValidation() {
if (!ConditionalizeRequest()) {
couldnt_conditionalize_request_ = true;
UpdateTransactionPattern(PATTERN_ENTRY_CANT_CONDITIONALIZE);
- if (partial_.get())
+ if (partial_)
return DoRestartPartialRequest();
DCHECK_NE(206, response_.headers->response_code());
@@ -2174,38 +2194,34 @@ int HttpCache::Transaction::BeginCacheValidation() {
}
int HttpCache::Transaction::BeginPartialCacheValidation() {
- DCHECK(mode_ == READ_WRITE);
+ DCHECK_EQ(mode_, READ_WRITE);
- if (response_.headers->response_code() != 206 && !partial_.get() &&
- !truncated_) {
+ if (response_.headers->response_code() != 206 && !partial_ && !truncated_)
return BeginCacheValidation();
- }
// Partial requests should not be recorded in histograms.
UpdateTransactionPattern(PATTERN_NOT_COVERED);
- if (range_requested_) {
- next_state_ = STATE_CACHE_QUERY_DATA;
- return OK;
- }
-
- // The request is not for a range, but we have stored just ranges.
-
if (request_->method == "HEAD")
return BeginCacheValidation();
- partial_.reset(new PartialData());
- partial_->SetHeaders(request_->extra_headers);
- if (!custom_request_.get()) {
- custom_request_.reset(new HttpRequestInfo(*request_));
- request_ = custom_request_.get();
+ if (!range_requested_) {
+ // The request is not for a range, but we have stored just ranges.
+
+ partial_.reset(new PartialData());
+ partial_->SetHeaders(request_->extra_headers);
+ if (!custom_request_.get()) {
+ custom_request_.reset(new HttpRequestInfo(*request_));
+ request_ = custom_request_.get();
+ }
}
- return ValidateEntryHeadersAndContinue();
+ next_state_ = STATE_CACHE_QUERY_DATA;
+ return OK;
}
// This should only be called once per request.
int HttpCache::Transaction::ValidateEntryHeadersAndContinue() {
- DCHECK(mode_ == READ_WRITE);
+ DCHECK_EQ(mode_, READ_WRITE);
if (!partial_->UpdateFromStoredHeaders(
response_.headers.get(), entry_->disk_entry, truncated_)) {
@@ -2254,7 +2270,7 @@ int HttpCache::Transaction::BeginExternallyConditionalizedRequest() {
EXTERNALLY_CONDITIONALIZED_CACHE_USABLE;
if (mode_ == NONE)
type = EXTERNALLY_CONDITIONALIZED_MISMATCHED_VALIDATORS;
- else if (RequiresValidation())
+ else if (RequiresValidation() != VALIDATION_NONE)
type = EXTERNALLY_CONDITIONALIZED_CACHE_REQUIRES_VALIDATION;
// TODO(ricea): Add CACHE_USABLE_STALE once stale-while-revalidate CL landed.
@@ -2384,15 +2400,15 @@ bool HttpCache::Transaction::ConditionalizeRequest() {
if (etag_value.empty() && last_modified_value.empty())
return false;
- if (!partial_.get()) {
+ if (!partial_) {
// Need to customize the request, so this forces us to allocate :(
custom_request_.reset(new HttpRequestInfo(*request_));
request_ = custom_request_.get();
}
DCHECK(custom_request_.get());
- bool use_if_range = partial_.get() && !partial_->IsCurrentRangeCached() &&
- !invalid_range_;
+ bool use_if_range =
+ partial_ && !partial_->IsCurrentRangeCached() && !invalid_range_;
if (!use_if_range) {
// stale-while-revalidate is not useful when we only have a partial response
@@ -2426,7 +2442,7 @@ bool HttpCache::Transaction::ConditionalizeRequest() {
}
// For byte-range requests, make sure that we use only one way to validate
// the request.
- if (partial_.get() && !partial_->IsCurrentRangeCached())
+ if (partial_ && !partial_->IsCurrentRangeCached())
return true;
}
@@ -2490,7 +2506,7 @@ bool HttpCache::Transaction::ValidatePartialResponse() {
return true;
}
- if (!partial_.get()) {
+ if (!partial_) {
// We are not expecting 206 but we may have one.
if (partial_response)
IgnoreRangeRequest();
@@ -2591,7 +2607,7 @@ void HttpCache::Transaction::FixHeadersForHead() {
int HttpCache::Transaction::SetupEntryForRead() {
if (network_trans_)
ResetNetworkTransaction();
- if (partial_.get()) {
+ if (partial_) {
if (truncated_ || is_sparse_ || !invalid_range_) {
// We are going to return the saved response headers to the caller, so
// we may need to adjust them first.
@@ -2612,24 +2628,6 @@ int HttpCache::Transaction::SetupEntryForRead() {
return OK;
}
-
-int HttpCache::Transaction::ReadFromNetwork(IOBuffer* data, int data_len) {
- read_buf_ = data;
- io_buf_len_ = data_len;
- next_state_ = STATE_NETWORK_READ;
- return DoLoop(OK);
-}
-
-int HttpCache::Transaction::ReadFromEntry(IOBuffer* data, int data_len) {
- if (request_->method == "HEAD")
- return 0;
-
- read_buf_ = data;
- io_buf_len_ = data_len;
- next_state_ = STATE_CACHE_READ_DATA;
- return DoLoop(OK);
-}
-
int HttpCache::Transaction::WriteToEntry(int index, int offset,
IOBuffer* data, int data_len,
const CompletionCallback& callback) {
@@ -2637,7 +2635,7 @@ int HttpCache::Transaction::WriteToEntry(int index, int offset,
return data_len;
int rv = 0;
- if (!partial_.get() || !data_len) {
+ if (!partial_ || !data_len) {
rv = entry_->disk_entry->WriteData(index, offset, data, data_len, callback,
true);
} else {
@@ -2647,10 +2645,12 @@ int HttpCache::Transaction::WriteToEntry(int index, int offset,
}
int HttpCache::Transaction::WriteResponseInfoToEntry(bool truncated) {
- next_state_ = STATE_CACHE_WRITE_RESPONSE_COMPLETE;
if (!entry_)
return OK;
+ if (net_log_.IsCapturing())
+ net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_WRITE_INFO);
+
// Do not cache no-store content. Do not cache content with cert errors
// either. This is to prevent not reporting net errors when loading a
// resource from the cache. When we load a page over HTTPS with a cert error
@@ -2686,6 +2686,21 @@ int HttpCache::Transaction::WriteResponseInfoToEntry(bool truncated) {
io_buf_len_, io_callback_, true);
}
+int HttpCache::Transaction::OnWriteResponseInfoToEntryComplete(int result) {
+ if (!entry_)
+ return OK;
+ if (net_log_.IsCapturing()) {
+ net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_WRITE_INFO,
+ result);
+ }
+
+ if (result != io_buf_len_) {
+ DLOG(ERROR) << "failed to write response info to cache";
+ DoneWritingToEntry(false);
+ }
+ return OK;
+}
+
void HttpCache::Transaction::DoneWritingToEntry(bool success) {
if (!entry_)
return;
@@ -2807,10 +2822,13 @@ void HttpCache::Transaction::ResetNetworkTransaction() {
if (network_trans_->GetLoadTimingInfo(&load_timing))
old_network_trans_load_timing_.reset(new LoadTimingInfo(load_timing));
total_received_bytes_ += network_trans_->GetTotalReceivedBytes();
+ total_sent_bytes_ += network_trans_->GetTotalSentBytes();
ConnectionAttempts attempts;
network_trans_->GetConnectionAttempts(&attempts);
for (const auto& attempt : attempts)
old_connection_attempts_.push_back(attempt);
+ old_remote_endpoint_ = IPEndPoint();
+ network_trans_->GetRemoteEndpoint(&old_remote_endpoint_);
network_trans_.reset();
}
diff --git a/chromium/net/http/http_cache_transaction.h b/chromium/net/http/http_cache_transaction.h
index 9b151af37eb..482bb644977 100644
--- a/chromium/net/http/http_cache_transaction.h
+++ b/chromium/net/http/http_cache_transaction.h
@@ -9,6 +9,7 @@
#define NET_HTTP_HTTP_CACHE_TRANSACTION_H_
#include <stddef.h>
+#include <stdint.h>
#include <string>
@@ -19,6 +20,7 @@
#include "base/time/time.h"
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h"
+#include "net/base/ip_endpoint.h"
#include "net/base/load_states.h"
#include "net/base/request_priority.h"
#include "net/base/upload_progress.h"
@@ -141,13 +143,15 @@ class HttpCache::Transaction : public HttpTransaction {
const CompletionCallback& callback) override;
void StopCaching() override;
bool GetFullRequestHeaders(HttpRequestHeaders* headers) const override;
- int64 GetTotalReceivedBytes() const override;
+ int64_t GetTotalReceivedBytes() const override;
+ int64_t GetTotalSentBytes() const override;
void DoneReading() override;
const HttpResponseInfo* GetResponseInfo() const override;
LoadState GetLoadState() const override;
UploadProgress GetUploadProgress(void) const override;
void SetQuicServerInfo(QuicServerInfo* quic_server_info) override;
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
+ bool GetRemoteEndpoint(IPEndPoint* endpoint) const override;
void SetPriority(RequestPriority priority) override;
void SetWebSocketHandshakeStreamCreateHelper(
WebSocketHandshakeStreamBase::CreateHelper* create_helper) override;
@@ -170,49 +174,55 @@ class HttpCache::Transaction : public HttpTransaction {
};
enum State {
+ // Normally, states are traversed in approximately this order.
STATE_NONE,
STATE_GET_BACKEND,
STATE_GET_BACKEND_COMPLETE,
- STATE_SEND_REQUEST,
- STATE_SEND_REQUEST_COMPLETE,
- STATE_SUCCESSFUL_SEND_REQUEST,
- STATE_NETWORK_READ,
- STATE_NETWORK_READ_COMPLETE,
STATE_INIT_ENTRY,
STATE_OPEN_ENTRY,
STATE_OPEN_ENTRY_COMPLETE,
- STATE_CREATE_ENTRY,
- STATE_CREATE_ENTRY_COMPLETE,
STATE_DOOM_ENTRY,
STATE_DOOM_ENTRY_COMPLETE,
+ STATE_CREATE_ENTRY,
+ STATE_CREATE_ENTRY_COMPLETE,
STATE_ADD_TO_ENTRY,
STATE_ADD_TO_ENTRY_COMPLETE,
+ STATE_CACHE_READ_RESPONSE,
+ STATE_CACHE_READ_RESPONSE_COMPLETE,
+ STATE_TOGGLE_UNUSED_SINCE_PREFETCH,
+ STATE_TOGGLE_UNUSED_SINCE_PREFETCH_COMPLETE,
+ STATE_CACHE_DISPATCH_VALIDATION,
+ STATE_CACHE_QUERY_DATA,
+ STATE_CACHE_QUERY_DATA_COMPLETE,
STATE_START_PARTIAL_CACHE_VALIDATION,
STATE_COMPLETE_PARTIAL_CACHE_VALIDATION,
+ STATE_SEND_REQUEST,
+ STATE_SEND_REQUEST_COMPLETE,
+ STATE_SUCCESSFUL_SEND_REQUEST,
STATE_UPDATE_CACHED_RESPONSE,
+ STATE_CACHE_WRITE_UPDATED_RESPONSE,
+ STATE_CACHE_WRITE_UPDATED_RESPONSE_COMPLETE,
STATE_UPDATE_CACHED_RESPONSE_COMPLETE,
STATE_OVERWRITE_CACHED_RESPONSE,
+ STATE_CACHE_WRITE_RESPONSE,
+ STATE_CACHE_WRITE_RESPONSE_COMPLETE,
STATE_TRUNCATE_CACHED_DATA,
STATE_TRUNCATE_CACHED_DATA_COMPLETE,
STATE_TRUNCATE_CACHED_METADATA,
STATE_TRUNCATE_CACHED_METADATA_COMPLETE,
STATE_PARTIAL_HEADERS_RECEIVED,
- STATE_CACHE_READ_RESPONSE,
- STATE_CACHE_READ_RESPONSE_COMPLETE,
- STATE_CACHE_DISPATCH_VALIDATION,
- STATE_TOGGLE_UNUSED_SINCE_PREFETCH,
- STATE_TOGGLE_UNUSED_SINCE_PREFETCH_COMPLETE,
- STATE_CACHE_WRITE_RESPONSE,
- STATE_CACHE_WRITE_TRUNCATED_RESPONSE,
- STATE_CACHE_WRITE_RESPONSE_COMPLETE,
STATE_CACHE_READ_METADATA,
STATE_CACHE_READ_METADATA_COMPLETE,
- STATE_CACHE_QUERY_DATA,
- STATE_CACHE_QUERY_DATA_COMPLETE,
+
+ // These states are entered from Read/AddTruncatedFlag.
+ STATE_NETWORK_READ,
+ STATE_NETWORK_READ_COMPLETE,
STATE_CACHE_READ_DATA,
STATE_CACHE_READ_DATA_COMPLETE,
STATE_CACHE_WRITE_DATA,
- STATE_CACHE_WRITE_DATA_COMPLETE
+ STATE_CACHE_WRITE_DATA_COMPLETE,
+ STATE_CACHE_WRITE_TRUNCATED_RESPONSE,
+ STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE
};
// Used for categorizing transactions for reporting in histograms. Patterns
@@ -232,14 +242,8 @@ class HttpCache::Transaction : public HttpTransaction {
PATTERN_MAX,
};
- // This is a helper function used to trigger a completion callback. It may
- // only be called if callback_ is non-null.
- void DoCallback(int rv);
-
- // This will trigger the completion callback if appropriate.
- int HandleResult(int rv);
-
- // Runs the state transition loop.
+ // Runs the state transition loop. Resets and calls |callback_| on exit,
+ // unless the return value is ERR_IO_PENDING.
int DoLoop(int result);
// Each of these methods corresponds to a State value. If there is an
@@ -247,46 +251,49 @@ class HttpCache::Transaction : public HttpTransaction {
// corresponding callback.
int DoGetBackend();
int DoGetBackendComplete(int result);
- int DoSendRequest();
- int DoSendRequestComplete(int result);
- int DoSuccessfulSendRequest();
- int DoNetworkRead();
- int DoNetworkReadComplete(int result);
int DoInitEntry();
int DoOpenEntry();
int DoOpenEntryComplete(int result);
- int DoCreateEntry();
- int DoCreateEntryComplete(int result);
int DoDoomEntry();
int DoDoomEntryComplete(int result);
+ int DoCreateEntry();
+ int DoCreateEntryComplete(int result);
int DoAddToEntry();
int DoAddToEntryComplete(int result);
+ int DoCacheReadResponse();
+ int DoCacheReadResponseComplete(int result);
+ int DoCacheToggleUnusedSincePrefetch();
+ int DoCacheToggleUnusedSincePrefetchComplete(int result);
+ int DoCacheDispatchValidation();
+ int DoCacheQueryData();
+ int DoCacheQueryDataComplete(int result);
int DoStartPartialCacheValidation();
int DoCompletePartialCacheValidation(int result);
+ int DoSendRequest();
+ int DoSendRequestComplete(int result);
+ int DoSuccessfulSendRequest();
int DoUpdateCachedResponse();
+ int DoCacheWriteUpdatedResponse();
+ int DoCacheWriteUpdatedResponseComplete(int result);
int DoUpdateCachedResponseComplete(int result);
int DoOverwriteCachedResponse();
+ int DoCacheWriteResponse();
+ int DoCacheWriteResponseComplete(int result);
int DoTruncateCachedData();
int DoTruncateCachedDataComplete(int result);
int DoTruncateCachedMetadata();
int DoTruncateCachedMetadataComplete(int result);
int DoPartialHeadersReceived();
- int DoCacheReadResponse();
- int DoCacheReadResponseComplete(int result);
- int DoCacheDispatchValidation();
- int DoCacheToggleUnusedSincePrefetch();
- int DoCacheToggleUnusedSincePrefetchComplete(int result);
- int DoCacheWriteResponse();
- int DoCacheWriteTruncatedResponse();
- int DoCacheWriteResponseComplete(int result);
int DoCacheReadMetadata();
int DoCacheReadMetadataComplete(int result);
- int DoCacheQueryData();
- int DoCacheQueryDataComplete(int result);
+ int DoNetworkRead();
+ int DoNetworkReadComplete(int result);
int DoCacheReadData();
int DoCacheReadDataComplete(int result);
int DoCacheWriteData(int num_bytes);
int DoCacheWriteDataComplete(int result);
+ int DoCacheWriteTruncatedResponse();
+ int DoCacheWriteTruncatedResponseComplete(int result);
// These functions are involved in a field trial testing storing certificates
// in seperate entries from the HttpResponseInfo.
@@ -354,12 +361,6 @@ class HttpCache::Transaction : public HttpTransaction {
// Setups the transaction for reading from the cache entry.
int SetupEntryForRead();
- // Reads data from the network.
- int ReadFromNetwork(IOBuffer* data, int data_len);
-
- // Reads data from the cache entry.
- int ReadFromEntry(IOBuffer* data, int data_len);
-
// Called to write data to the cache entry. If the write fails, then the
// cache entry is destroyed. Future calls to this function will just do
// nothing without side-effect. Returns a network error code.
@@ -370,6 +371,14 @@ class HttpCache::Transaction : public HttpTransaction {
// entry should be marked as incomplete.
int WriteResponseInfoToEntry(bool truncated);
+ // Helper function, should be called with result of WriteResponseInfoToEntry
+ // (or the result of the callback, when WriteResponseInfoToEntry returns
+ // ERR_IO_PENDING). Calls DoneWritingToEntry if |result| is not the right
+ // number of bytes. It is expected that the state that calls this will
+ // return whatever net error code this function returns, which currently
+ // is always "OK".
+ int OnWriteResponseInfoToEntryComplete(int result);
+
// Called when we are done writing to the cache entry.
void DoneWritingToEntry(bool success);
@@ -436,7 +445,6 @@ class HttpCache::Transaction : public HttpTransaction {
const HttpResponseInfo* new_response_;
std::string cache_key_;
Mode mode_;
- State target_state_;
bool reading_; // We are already reading. Never reverts to false once set.
bool invalid_range_; // We may bypass the cache for this request.
bool truncated_; // We don't have all the response data.
@@ -464,7 +472,8 @@ class HttpCache::Transaction : public HttpTransaction {
base::TimeTicks first_cache_access_since_;
base::TimeTicks send_request_since_;
- int64 total_received_bytes_;
+ int64_t total_received_bytes_;
+ int64_t total_sent_bytes_;
// Load timing information for the last network request, if any. Set in the
// 304 and 206 response cases, as the network transaction may be destroyed
@@ -472,6 +481,7 @@ class HttpCache::Transaction : public HttpTransaction {
scoped_ptr<LoadTimingInfo> old_network_trans_load_timing_;
ConnectionAttempts old_connection_attempts_;
+ IPEndPoint old_remote_endpoint_;
// The helper object to use to create WebSocketHandshakeStreamBase
// objects. Only relevant when establishing a WebSocket connection.
diff --git a/chromium/net/http/http_cache_unittest.cc b/chromium/net/http/http_cache_unittest.cc
index f490444356f..6eeef8f1157 100644
--- a/chromium/net/http/http_cache_unittest.cc
+++ b/chromium/net/http/http_cache_unittest.cc
@@ -4,6 +4,8 @@
#include "net/http/http_cache.h"
+#include <stdint.h>
+
#include <algorithm>
#include "base/bind.h"
@@ -17,6 +19,7 @@
#include "net/base/cache_type.h"
#include "net/base/elements_upload_data_stream.h"
#include "net/base/host_port_pair.h"
+#include "net/base/ip_endpoint.h"
#include "net/base/load_flags.h"
#include "net/base/load_timing_info.h"
#include "net/base/load_timing_info_test_util.h"
@@ -136,7 +139,9 @@ void RunTransactionTestBase(HttpCache* cache,
HttpResponseInfo* response_info,
const BoundNetLog& net_log,
LoadTimingInfo* load_timing_info,
- int64* received_bytes) {
+ int64_t* sent_bytes,
+ int64_t* received_bytes,
+ IPEndPoint* remote_endpoint) {
TestCompletionCallback callback;
// write to the cache
@@ -168,8 +173,13 @@ void RunTransactionTestBase(HttpCache* cache,
trans->GetLoadTimingInfo(load_timing_info);
}
+ if (remote_endpoint)
+ ASSERT_TRUE(trans->GetRemoteEndpoint(remote_endpoint));
+
ReadAndVerifyTransaction(trans.get(), trans_info);
+ if (sent_bytes)
+ *sent_bytes = trans->GetTotalSentBytes();
if (received_bytes)
*received_bytes = trans->GetTotalReceivedBytes();
}
@@ -179,7 +189,7 @@ void RunTransactionTestWithRequest(HttpCache* cache,
const MockHttpRequest& request,
HttpResponseInfo* response_info) {
RunTransactionTestBase(cache, trans_info, request, response_info,
- BoundNetLog(), NULL, NULL);
+ BoundNetLog(), nullptr, nullptr, nullptr, nullptr);
}
void RunTransactionTestAndGetTiming(HttpCache* cache,
@@ -187,17 +197,29 @@ void RunTransactionTestAndGetTiming(HttpCache* cache,
const BoundNetLog& log,
LoadTimingInfo* load_timing_info) {
RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
- NULL, log, load_timing_info, NULL);
+ nullptr, log, load_timing_info, nullptr, nullptr,
+ nullptr);
+}
+
+void RunTransactionTestAndGetTimingAndConnectedSocketAddress(
+ HttpCache* cache,
+ const MockTransaction& trans_info,
+ const BoundNetLog& log,
+ LoadTimingInfo* load_timing_info,
+ IPEndPoint* remote_endpoint) {
+ RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
+ nullptr, log, load_timing_info, nullptr, nullptr,
+ remote_endpoint);
}
void RunTransactionTest(HttpCache* cache, const MockTransaction& trans_info) {
- RunTransactionTestAndGetTiming(cache, trans_info, BoundNetLog(), NULL);
+ RunTransactionTestAndGetTiming(cache, trans_info, BoundNetLog(), nullptr);
}
void RunTransactionTestWithLog(HttpCache* cache,
const MockTransaction& trans_info,
const BoundNetLog& log) {
- RunTransactionTestAndGetTiming(cache, trans_info, log, NULL);
+ RunTransactionTestAndGetTiming(cache, trans_info, log, nullptr);
}
void RunTransactionTestWithResponseInfo(HttpCache* cache,
@@ -214,7 +236,8 @@ void RunTransactionTestWithResponseInfoAndGetTiming(
const BoundNetLog& log,
LoadTimingInfo* load_timing_info) {
RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
- response, log, load_timing_info, NULL);
+ response, log, load_timing_info, nullptr, nullptr,
+ nullptr);
}
void RunTransactionTestWithResponse(HttpCache* cache,
@@ -233,7 +256,8 @@ void RunTransactionTestWithResponseAndGetTiming(
LoadTimingInfo* load_timing_info) {
HttpResponseInfo response;
RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
- &response, log, load_timing_info, NULL);
+ &response, log, load_timing_info, nullptr, nullptr,
+ nullptr);
response.headers->GetNormalizedHeaders(response_headers);
}
@@ -458,7 +482,7 @@ const char kFullRangeData[] =
// Verifies the response headers (|response|) match a partial content
// response for the range starting at |start| and ending at |end|.
-void Verify206Response(std::string response, int start, int end) {
+void Verify206Response(const std::string& response, int start, int end) {
std::string raw_headers(
HttpUtil::AssembleRawHeaders(response.data(), response.size()));
scoped_refptr<HttpResponseHeaders> headers(
@@ -503,6 +527,24 @@ void CreateTruncatedEntry(std::string raw_headers, MockHttpCache* cache) {
entry->Close();
}
+// Verifies that there's an entry with this |key| with the truncated flag set to
+// |flag_value|, and with an optional |data_size| (if not zero).
+void VerifyTruncatedFlag(MockHttpCache* cache,
+ const std::string& key,
+ bool flag_value,
+ int data_size) {
+ disk_cache::Entry* entry;
+ ASSERT_TRUE(cache->OpenBackendEntry(key, &entry));
+ disk_cache::ScopedEntryPtr closer(entry);
+
+ HttpResponseInfo response;
+ bool truncated = !flag_value;
+ EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
+ EXPECT_EQ(flag_value, truncated);
+ if (data_size)
+ EXPECT_EQ(data_size, entry->GetDataSize(1));
+}
+
// Helper to represent a network HTTP response.
struct Response {
// Set this response into |trans|.
@@ -1909,7 +1951,14 @@ TEST(HttpCache, DeleteCacheWaitingForBackend2) {
EXPECT_FALSE(cb2.have_result());
}
-TEST(HttpCache, TypicalGET_ConditionalRequest) {
+// Fails only on bots. crbug.com/533640
+#if defined(OS_ANDROID)
+#define MAYBE_TypicalGET_ConditionalRequest \
+ DISABLED_TypicalGET_ConditionalRequest
+#else
+#define MAYBE_TypicalGET_ConditionalRequest TypicalGET_ConditionalRequest
+#endif
+TEST(HttpCache, MAYBE_TypicalGET_ConditionalRequest) {
MockHttpCache cache;
// write to the cache
@@ -1961,13 +2010,17 @@ TEST(HttpCache, ETagGET_ConditionalRequest_304) {
transaction.handler = ETagGet_ConditionalRequest_Handler;
BoundTestNetLog log;
LoadTimingInfo load_timing_info;
- RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
- &load_timing_info);
+ IPEndPoint remote_endpoint;
+ RunTransactionTestAndGetTimingAndConnectedSocketAddress(
+ cache.http_cache(), transaction, log.bound(), &load_timing_info,
+ &remote_endpoint);
EXPECT_EQ(2, cache.network_layer()->transaction_count());
EXPECT_EQ(1, cache.disk_cache()->open_count());
EXPECT_EQ(1, cache.disk_cache()->create_count());
TestLoadTimingNetworkRequest(load_timing_info);
+
+ EXPECT_FALSE(remote_endpoint.address().empty());
}
class RevalidationServer {
@@ -3985,9 +4038,15 @@ TEST(HttpCache, RangeGET_NoContentLength) {
RemoveMockTransaction(&transaction);
}
+// Fails only on bots. crbug.com/533640
+#if defined(OS_ANDROID)
+#define MAYBE_RangeGET_OK DISABLED_RangeGET_OK
+#else
+#define MAYBE_RangeGET_OK RangeGET_OK
+#endif
// Tests that we can cache range requests and fetch random blocks from the
// cache and the network.
-TEST(HttpCache, RangeGET_OK) {
+TEST(HttpCache, MAYBE_RangeGET_OK) {
MockHttpCache cache;
AddMockTransaction(&kRangeGET_TransactionOK);
std::string headers;
@@ -4045,9 +4104,15 @@ TEST(HttpCache, RangeGET_OK) {
RemoveMockTransaction(&kRangeGET_TransactionOK);
}
+// Fails only on bots. crbug.com/533640
+#if defined(OS_ANDROID)
+#define MAYBE_RangeGET_SyncOK DISABLED_RangeGET_SyncOK
+#else
+#define MAYBE_RangeGET_SyncOK RangeGET_SyncOK
+#endif
// Tests that we can cache range requests and fetch random blocks from the
// cache and the network, with synchronous responses.
-TEST(HttpCache, RangeGET_SyncOK) {
+TEST(HttpCache, MAYBE_RangeGET_SyncOK) {
MockHttpCache cache;
MockTransaction transaction(kRangeGET_TransactionOK);
@@ -4105,6 +4170,34 @@ TEST(HttpCache, RangeGET_SyncOK) {
RemoveMockTransaction(&transaction);
}
+// Tests that if the previous transaction is cancelled while busy (doing sparse
+// IO), a new transaction (that reuses that same ActiveEntry) waits until the
+// entry is ready again.
+TEST(HttpCache, Sparse_WaitForEntry) {
+ MockHttpCache cache;
+
+ ScopedMockTransaction transaction(kRangeGET_TransactionOK);
+
+ // Create a sparse entry.
+ RunTransactionTest(cache.http_cache(), transaction);
+
+ // Simulate a previous transaction being cancelled.
+ disk_cache::Entry* entry;
+ ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
+ entry->CancelSparseIO();
+
+ // Test with a range request.
+ RunTransactionTest(cache.http_cache(), transaction);
+
+ // Now test with a regular request.
+ entry->CancelSparseIO();
+ transaction.request_headers = EXTRA_HEADER;
+ transaction.data = kFullRangeData;
+ RunTransactionTest(cache.http_cache(), transaction);
+
+ entry->Close();
+}
+
// Tests that we don't revalidate an entry unless we are required to do so.
TEST(HttpCache, RangeGET_Revalidate1) {
MockHttpCache cache;
@@ -4154,8 +4247,14 @@ TEST(HttpCache, RangeGET_Revalidate1) {
RemoveMockTransaction(&transaction);
}
+// Fails only on bots. crbug.com/533640
+#if defined(OS_ANDROID)
+#define MAYBE_RangeGET_Revalidate2 DISABLED_RangeGET_Revalidate2
+#else
+#define MAYBE_RangeGET_Revalidate2 RangeGET_Revalidate2
+#endif
// Checks that we revalidate an entry when the headers say so.
-TEST(HttpCache, RangeGET_Revalidate2) {
+TEST(HttpCache, MAYBE_RangeGET_Revalidate2) {
MockHttpCache cache;
std::string headers;
@@ -4886,8 +4985,14 @@ TEST(HttpCache, GET_Previous206_NotValidation) {
EXPECT_EQ(2, cache.disk_cache()->create_count());
}
+// Fails only on bots. crbug.com/533640
+#if defined(OS_ANDROID)
+#define MAYBE_RangeGET_Previous200 DISABLED_RangeGET_Previous200
+#else
+#define MAYBE_RangeGET_Previous200 RangeGET_Previous200
+#endif
// Tests that we can handle range requests with cached 200 responses.
-TEST(HttpCache, RangeGET_Previous200) {
+TEST(HttpCache, MAYBE_RangeGET_Previous200) {
MockHttpCache cache;
// Store the whole thing with status 200.
@@ -5028,8 +5133,14 @@ TEST(HttpCache, RangeGET_MoreThanCurrentSize) {
RemoveMockTransaction(&kRangeGET_TransactionOK);
}
+// Fails only on bots. crbug.com/533640
+#if defined(OS_ANDROID)
+#define MAYBE_RangeGET_Cancel DISABLED_RangeGET_Cancel
+#else
+#define MAYBE_RangeGET_Cancel RangeGET_Cancel
+#endif
// Tests that we don't delete a sparse entry when we cancel a request.
-TEST(HttpCache, RangeGET_Cancel) {
+TEST(HttpCache, MAYBE_RangeGET_Cancel) {
MockHttpCache cache;
AddMockTransaction(&kRangeGET_TransactionOK);
@@ -5064,9 +5175,15 @@ TEST(HttpCache, RangeGET_Cancel) {
RemoveMockTransaction(&kRangeGET_TransactionOK);
}
+// Fails only on bots. crbug.com/533640
+#if defined(OS_ANDROID)
+#define MAYBE_RangeGET_Cancel2 DISABLED_RangeGET_Cancel2
+#else
+#define MAYBE_RangeGET_Cancel2 RangeGET_Cancel2
+#endif
// Tests that we don't delete a sparse entry when we start a new request after
// cancelling the previous one.
-TEST(HttpCache, RangeGET_Cancel2) {
+TEST(HttpCache, MAYBE_RangeGET_Cancel2) {
MockHttpCache cache;
AddMockTransaction(&kRangeGET_TransactionOK);
@@ -5606,12 +5723,11 @@ TEST(HttpCache, DoomOnDestruction3) {
TEST(HttpCache, SetTruncatedFlag) {
MockHttpCache cache;
- MockTransaction transaction(kSimpleGET_Transaction);
+ ScopedMockTransaction transaction(kSimpleGET_Transaction);
transaction.response_headers =
"Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
"Content-Length: 22\n"
"Etag: \"foopy\"\n";
- AddMockTransaction(&transaction);
MockHttpRequest request(transaction);
scoped_ptr<Context> c(new Context());
@@ -5653,27 +5769,18 @@ TEST(HttpCache, SetTruncatedFlag) {
EXPECT_FALSE(c->callback.have_result());
// Verify that the entry is marked as incomplete.
- disk_cache::Entry* entry;
- ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
- HttpResponseInfo response;
- bool truncated = false;
- EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
- EXPECT_TRUE(truncated);
- entry->Close();
-
- RemoveMockTransaction(&transaction);
+ VerifyTruncatedFlag(&cache, kSimpleGET_Transaction.url, true, 0);
}
// Tests that we don't mark an entry as truncated when we read everything.
TEST(HttpCache, DontSetTruncatedFlag) {
MockHttpCache cache;
- MockTransaction transaction(kSimpleGET_Transaction);
+ ScopedMockTransaction transaction(kSimpleGET_Transaction);
transaction.response_headers =
"Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
"Content-Length: 22\n"
"Etag: \"foopy\"\n";
- AddMockTransaction(&transaction);
MockHttpRequest request(transaction);
scoped_ptr<Context> c(new Context());
@@ -5692,21 +5799,66 @@ TEST(HttpCache, DontSetTruncatedFlag) {
c->trans.reset();
// Verify that the entry is not marked as truncated.
- disk_cache::Entry* entry;
- ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
- HttpResponseInfo response;
- bool truncated = true;
- EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
- EXPECT_FALSE(truncated);
- entry->Close();
+ VerifyTruncatedFlag(&cache, kSimpleGET_Transaction.url, false, 0);
+}
- RemoveMockTransaction(&transaction);
+// Tests that sparse entries don't set the truncate flag.
+TEST(HttpCache, RangeGET_DontTruncate) {
+ MockHttpCache cache;
+
+ ScopedMockTransaction transaction(kRangeGET_TransactionOK);
+ transaction.request_headers = "Range: bytes = 0-19\r\n" EXTRA_HEADER;
+
+ scoped_ptr<MockHttpRequest> request(new MockHttpRequest(transaction));
+ scoped_ptr<HttpTransaction> trans;
+
+ int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
+ EXPECT_EQ(OK, rv);
+
+ TestCompletionCallback cb;
+ rv = trans->Start(request.get(), cb.callback(), BoundNetLog());
+ EXPECT_EQ(0, cb.GetResult(rv));
+
+ scoped_refptr<IOBuffer> buf(new IOBuffer(10));
+ rv = trans->Read(buf.get(), 10, cb.callback());
+ EXPECT_EQ(10, cb.GetResult(rv));
+
+ // Should not trigger any DCHECK.
+ trans.reset();
+ VerifyTruncatedFlag(&cache, kRangeGET_TransactionOK.url, false, 0);
+}
+
+// Tests that sparse entries don't set the truncate flag (when the byte range
+// starts after 0).
+TEST(HttpCache, RangeGET_DontTruncate2) {
+ MockHttpCache cache;
+
+ ScopedMockTransaction transaction(kRangeGET_TransactionOK);
+ transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
+
+ scoped_ptr<MockHttpRequest> request(new MockHttpRequest(transaction));
+ scoped_ptr<HttpTransaction> trans;
+
+ int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
+ EXPECT_EQ(OK, rv);
+
+ TestCompletionCallback cb;
+ rv = trans->Start(request.get(), cb.callback(), BoundNetLog());
+ EXPECT_EQ(0, cb.GetResult(rv));
+
+ scoped_refptr<IOBuffer> buf(new IOBuffer(10));
+ rv = trans->Read(buf.get(), 10, cb.callback());
+ EXPECT_EQ(10, cb.GetResult(rv));
+
+ // Should not trigger any DCHECK.
+ trans.reset();
+ VerifyTruncatedFlag(&cache, kRangeGET_TransactionOK.url, false, 0);
}
// Tests that we can continue with a request that was interrupted.
TEST(HttpCache, GET_IncompleteResource) {
MockHttpCache cache;
- AddMockTransaction(&kRangeGET_TransactionOK);
+ ScopedMockTransaction transaction(kRangeGET_TransactionOK);
std::string raw_headers("HTTP/1.1 200 OK\n"
"Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
@@ -5717,7 +5869,6 @@ TEST(HttpCache, GET_IncompleteResource) {
// Now make a regular request.
std::string headers;
- MockTransaction transaction(kRangeGET_TransactionOK);
transaction.request_headers = EXTRA_HEADER;
transaction.data = kFullRangeData;
RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
@@ -5736,16 +5887,7 @@ TEST(HttpCache, GET_IncompleteResource) {
EXPECT_EQ(1, cache.disk_cache()->create_count());
// Verify that the disk entry was updated.
- disk_cache::Entry* entry;
- ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
- EXPECT_EQ(80, entry->GetDataSize(1));
- bool truncated = true;
- HttpResponseInfo response;
- EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
- EXPECT_FALSE(truncated);
- entry->Close();
-
- RemoveMockTransaction(&kRangeGET_TransactionOK);
+ VerifyTruncatedFlag(&cache, kRangeGET_TransactionOK.url, false, 80);
}
// Tests the handling of no-store when revalidating a truncated entry.
@@ -6011,7 +6153,7 @@ TEST(HttpCache, TransactionRetryLimit) {
// Tests that we cache a 200 response to the validation request.
TEST(HttpCache, GET_IncompleteResource4) {
MockHttpCache cache;
- AddMockTransaction(&kRangeGET_TransactionOK);
+ ScopedMockTransaction transaction(kRangeGET_TransactionOK);
std::string raw_headers("HTTP/1.1 200 OK\n"
"Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
@@ -6022,7 +6164,6 @@ TEST(HttpCache, GET_IncompleteResource4) {
// Now make a regular request.
std::string headers;
- MockTransaction transaction(kRangeGET_TransactionOK);
transaction.request_headers = EXTRA_HEADER;
transaction.data = "Not a range";
RangeTransactionServer handler;
@@ -6034,23 +6175,14 @@ TEST(HttpCache, GET_IncompleteResource4) {
EXPECT_EQ(1, cache.disk_cache()->create_count());
// Verify that the disk entry was updated.
- disk_cache::Entry* entry;
- ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
- EXPECT_EQ(11, entry->GetDataSize(1));
- bool truncated = true;
- HttpResponseInfo response;
- EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
- EXPECT_FALSE(truncated);
- entry->Close();
-
- RemoveMockTransaction(&kRangeGET_TransactionOK);
+ VerifyTruncatedFlag(&cache, kRangeGET_TransactionOK.url, false, 11);
}
// Tests that when we cancel a request that was interrupted, we mark it again
// as truncated.
TEST(HttpCache, GET_CancelIncompleteResource) {
MockHttpCache cache;
- AddMockTransaction(&kRangeGET_TransactionOK);
+ ScopedMockTransaction transaction(kRangeGET_TransactionOK);
std::string raw_headers("HTTP/1.1 200 OK\n"
"Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
@@ -6060,7 +6192,6 @@ TEST(HttpCache, GET_CancelIncompleteResource) {
CreateTruncatedEntry(raw_headers, &cache);
// Now make a regular request.
- MockTransaction transaction(kRangeGET_TransactionOK);
transaction.request_headers = EXTRA_HEADER;
MockHttpRequest request(transaction);
@@ -6087,15 +6218,7 @@ TEST(HttpCache, GET_CancelIncompleteResource) {
EXPECT_EQ(1, cache.disk_cache()->create_count());
// Verify that the disk entry was updated: now we have 30 bytes.
- disk_cache::Entry* entry;
- ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
- EXPECT_EQ(30, entry->GetDataSize(1));
- bool truncated = false;
- HttpResponseInfo response;
- EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
- EXPECT_TRUE(truncated);
- entry->Close();
- RemoveMockTransaction(&kRangeGET_TransactionOK);
+ VerifyTruncatedFlag(&cache, kRangeGET_TransactionOK.url, true, 30);
}
// Tests that we can handle range requests when we have a truncated entry.
@@ -6842,7 +6965,7 @@ TEST(HttpCache, StopCachingSavesEntry) {
ASSERT_EQ(OK, cache.CreateTransaction(&trans));
// Force a response that can be resumed.
- MockTransaction mock_transaction(kSimpleGET_Transaction);
+ ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
AddMockTransaction(&mock_transaction);
mock_transaction.response_headers = "Cache-Control: max-age=10000\n"
"Content-Length: 42\n"
@@ -6862,18 +6985,10 @@ TEST(HttpCache, StopCachingSavesEntry) {
EXPECT_GT(callback.GetResult(rv), 0);
rv = trans->Read(buf.get(), 256, callback.callback());
EXPECT_EQ(callback.GetResult(rv), 0);
-
- RemoveMockTransaction(&mock_transaction);
}
// Verify that the entry is marked as incomplete.
- disk_cache::Entry* entry;
- ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
- HttpResponseInfo response;
- bool truncated = false;
- EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
- EXPECT_TRUE(truncated);
- entry->Close();
+ VerifyTruncatedFlag(&cache, kSimpleGET_Transaction.url, true, 0);
}
// Tests that we handle truncated enries when StopCaching is called.
@@ -6917,15 +7032,7 @@ TEST(HttpCache, StopCachingTruncatedEntry) {
}
// Verify that the disk entry was updated.
- disk_cache::Entry* entry;
- ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
- EXPECT_EQ(80, entry->GetDataSize(1));
- bool truncated = true;
- HttpResponseInfo response;
- EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
- EXPECT_FALSE(truncated);
- entry->Close();
-
+ VerifyTruncatedFlag(&cache, kRangeGET_TransactionOK.url, false, 80);
RemoveMockTransaction(&kRangeGET_TransactionOK);
}
@@ -6965,13 +7072,7 @@ TEST(HttpCache, TruncatedByContentLength2) {
RemoveMockTransaction(&transaction);
// Verify that the entry is marked as incomplete.
- disk_cache::Entry* entry;
- ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
- HttpResponseInfo response;
- bool truncated = false;
- EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
- EXPECT_TRUE(truncated);
- entry->Close();
+ VerifyTruncatedFlag(&cache, kSimpleGET_Transaction.url, true, 0);
}
// Make sure that calling SetPriority on a cache transaction passes on
@@ -7080,46 +7181,50 @@ TEST(HttpCache, SetPriorityNewTransaction) {
RemoveMockTransaction(&kRangeGET_TransactionOK);
}
-int64 RunTransactionAndGetReceivedBytes(
- MockHttpCache& cache,
- const MockTransaction& trans_info) {
- int64 received_bytes = -1;
+namespace {
+
+void RunTransactionAndGetNetworkBytes(MockHttpCache& cache,
+ const MockTransaction& trans_info,
+ int64_t* sent_bytes,
+ int64_t* received_bytes) {
RunTransactionTestBase(cache.http_cache(), trans_info,
- MockHttpRequest(trans_info), NULL, BoundNetLog(), NULL,
- &received_bytes);
- return received_bytes;
+ MockHttpRequest(trans_info), nullptr, BoundNetLog(),
+ nullptr, sent_bytes, received_bytes, nullptr);
}
-int64 TransactionSize(const MockTransaction& transaction) {
- return strlen(transaction.status) + strlen(transaction.response_headers) +
- strlen(transaction.data);
-}
+} // namespace
-TEST(HttpCache, ReceivedBytesCacheMissAndThenHit) {
+TEST(HttpCache, NetworkBytesCacheMissAndThenHit) {
MockHttpCache cache;
MockTransaction transaction(kSimpleGET_Transaction);
- int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
- EXPECT_EQ(TransactionSize(transaction), received_bytes);
+ int64_t sent, received;
+ RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
+ EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
+ EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
- received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
- EXPECT_EQ(0, received_bytes);
+ RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
+ EXPECT_EQ(0, sent);
+ EXPECT_EQ(0, received);
}
-TEST(HttpCache, ReceivedBytesConditionalRequest304) {
+TEST(HttpCache, NetworkBytesConditionalRequest304) {
MockHttpCache cache;
ScopedMockTransaction transaction(kETagGET_Transaction);
- int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
- EXPECT_EQ(TransactionSize(transaction), received_bytes);
+ int64_t sent, received;
+ RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
+ EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
+ EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
transaction.load_flags = LOAD_VALIDATE_CACHE;
transaction.handler = ETagGet_ConditionalRequest_Handler;
- received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
- EXPECT_EQ(TransactionSize(transaction), received_bytes);
+ RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
+ EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
+ EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
}
-TEST(HttpCache, ReceivedBytesConditionalRequest200) {
+TEST(HttpCache, NetworkBytesConditionalRequest200) {
MockHttpCache cache;
MockTransaction transaction(kTypicalGET_Transaction);
@@ -7131,45 +7236,52 @@ TEST(HttpCache, ReceivedBytesConditionalRequest200) {
"Cache-Control: max-age=0\n"
"Vary: Foo\n";
AddMockTransaction(&transaction);
- int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
- EXPECT_EQ(TransactionSize(transaction), received_bytes);
+ int64_t sent, received;
+ RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
+ EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
+ EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
RevalidationServer server;
transaction.handler = server.Handler;
transaction.request_headers = "Foo: none\r\n";
- received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
- EXPECT_EQ(TransactionSize(transaction), received_bytes);
+ RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
+ EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
+ EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
RemoveMockTransaction(&transaction);
}
-TEST(HttpCache, ReceivedBytesRange) {
+TEST(HttpCache, NetworkBytesRange) {
MockHttpCache cache;
AddMockTransaction(&kRangeGET_TransactionOK);
MockTransaction transaction(kRangeGET_TransactionOK);
// Read bytes 40-49 from the network.
- int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
- int64 range_response_size = TransactionSize(transaction);
- EXPECT_EQ(range_response_size, received_bytes);
+ int64_t sent, received;
+ RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
+ EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
+ EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
// Read bytes 40-49 from the cache.
- received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
- EXPECT_EQ(0, received_bytes);
+ RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
+ EXPECT_EQ(0, sent);
+ EXPECT_EQ(0, received);
base::MessageLoop::current()->RunUntilIdle();
// Read bytes 30-39 from the network.
transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
transaction.data = "rg: 30-39 ";
- received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
- EXPECT_EQ(range_response_size, received_bytes);
+ RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
+ EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
+ EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
base::MessageLoop::current()->RunUntilIdle();
// Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache.
transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
- received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
- EXPECT_EQ(range_response_size * 2, received_bytes);
+ RunTransactionAndGetNetworkBytes(cache, transaction, &sent, &received);
+ EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes * 2, sent);
+ EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes * 2, received);
RemoveMockTransaction(&kRangeGET_TransactionOK);
}
@@ -7349,6 +7461,83 @@ TEST(HttpCache, ResourceFreshnessHeaderNotSent) {
EXPECT_EQ(2, cache.network_layer()->transaction_count());
}
+TEST(HttpCache, StaleContentNotUsedWhenLoadFlagNotSet) {
+ MockHttpCache cache;
+
+ ScopedMockTransaction stale_while_revalidate_transaction(
+ kSimpleGET_Transaction);
+
+ stale_while_revalidate_transaction.response_headers =
+ "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
+ "Age: 10801\n"
+ "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
+
+ // Write to the cache.
+ RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
+
+ EXPECT_EQ(1, cache.network_layer()->transaction_count());
+
+ // Send the request again and check that it is sent to the network again.
+ HttpResponseInfo response_info;
+ RunTransactionTestWithResponseInfo(
+ cache.http_cache(), stale_while_revalidate_transaction, &response_info);
+
+ EXPECT_EQ(2, cache.network_layer()->transaction_count());
+ EXPECT_FALSE(response_info.async_revalidation_required);
+}
+
+TEST(HttpCache, StaleContentUsedWhenLoadFlagSetAndUsable) {
+ MockHttpCache cache;
+
+ ScopedMockTransaction stale_while_revalidate_transaction(
+ kSimpleGET_Transaction);
+ stale_while_revalidate_transaction.load_flags |=
+ LOAD_SUPPORT_ASYNC_REVALIDATION;
+ stale_while_revalidate_transaction.response_headers =
+ "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
+ "Age: 10801\n"
+ "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
+
+ // Write to the cache.
+ RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
+
+ EXPECT_EQ(1, cache.network_layer()->transaction_count());
+
+ // Send the request again and check that it is not sent to the network again.
+ HttpResponseInfo response_info;
+ RunTransactionTestWithResponseInfo(
+ cache.http_cache(), stale_while_revalidate_transaction, &response_info);
+
+ EXPECT_EQ(1, cache.network_layer()->transaction_count());
+ EXPECT_TRUE(response_info.async_revalidation_required);
+}
+
+TEST(HttpCache, StaleContentNotUsedWhenUnusable) {
+ MockHttpCache cache;
+
+ ScopedMockTransaction stale_while_revalidate_transaction(
+ kSimpleGET_Transaction);
+ stale_while_revalidate_transaction.load_flags |=
+ LOAD_SUPPORT_ASYNC_REVALIDATION;
+ stale_while_revalidate_transaction.response_headers =
+ "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
+ "Age: 10801\n"
+ "Cache-Control: max-age=0,stale-while-revalidate=1800\n";
+
+ // Write to the cache.
+ RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
+
+ EXPECT_EQ(1, cache.network_layer()->transaction_count());
+
+ // Send the request again and check that it is sent to the network again.
+ HttpResponseInfo response_info;
+ RunTransactionTestWithResponseInfo(
+ cache.http_cache(), stale_while_revalidate_transaction, &response_info);
+
+ EXPECT_EQ(2, cache.network_layer()->transaction_count());
+ EXPECT_FALSE(response_info.async_revalidation_required);
+}
+
// Tests that we allow multiple simultaneous, non-overlapping transactions to
// take place on a sparse entry.
TEST(HttpCache, RangeGET_MultipleRequests) {
diff --git a/chromium/net/http/http_content_disposition.cc b/chromium/net/http/http_content_disposition.cc
index 0e830f609bc..28ea8bd5547 100644
--- a/chromium/net/http/http_content_disposition.cc
+++ b/chromium/net/http/http_content_disposition.cc
@@ -359,9 +359,11 @@ std::string::const_iterator HttpContentDisposition::ConsumeDispositionType(
DCHECK(std::find(type_begin, type_end, '=') == type_end);
- if (base::LowerCaseEqualsASCII(type_begin, type_end, "inline")) {
+ if (base::LowerCaseEqualsASCII(base::StringPiece(type_begin, type_end),
+ "inline")) {
type_ = INLINE;
- } else if (base::LowerCaseEqualsASCII(type_begin, type_end, "attachment")) {
+ } else if (base::LowerCaseEqualsASCII(base::StringPiece(type_begin, type_end),
+ "attachment")) {
type_ = ATTACHMENT;
} else {
parse_result_flags_ |= HAS_UNKNOWN_DISPOSITION_TYPE;
@@ -403,15 +405,17 @@ void HttpContentDisposition::Parse(const std::string& header,
HttpUtil::NameValuePairsIterator iter(pos, end, ';');
while (iter.GetNext()) {
if (filename.empty() &&
- base::LowerCaseEqualsASCII(iter.name_begin(), iter.name_end(),
- "filename")) {
+ base::LowerCaseEqualsASCII(
+ base::StringPiece(iter.name_begin(), iter.name_end()),
+ "filename")) {
DecodeFilenameValue(iter.value(), referrer_charset, &filename,
&parse_result_flags_);
if (!filename.empty())
parse_result_flags_ |= HAS_FILENAME;
} else if (ext_filename.empty() &&
- base::LowerCaseEqualsASCII(iter.name_begin(), iter.name_end(),
- "filename*")) {
+ base::LowerCaseEqualsASCII(
+ base::StringPiece(iter.name_begin(), iter.name_end()),
+ "filename*")) {
DecodeExtValue(iter.raw_value(), &ext_filename);
if (!ext_filename.empty())
parse_result_flags_ |= HAS_EXT_FILENAME;
diff --git a/chromium/net/http/http_log_util.cc b/chromium/net/http/http_log_util.cc
index 0467fb605ab..87c2fd99f19 100644
--- a/chromium/net/http/http_log_util.cc
+++ b/chromium/net/http/http_log_util.cc
@@ -19,7 +19,7 @@ bool ShouldRedactChallenge(HttpAuthChallengeTokenizer* challenge) {
if (challenge->challenge_text().find(',') != std::string::npos)
return false;
- std::string scheme = base::StringToLowerASCII(challenge->scheme());
+ std::string scheme = base::ToLowerASCII(challenge->scheme());
// Invalid input.
if (scheme.empty())
return false;
@@ -45,15 +45,15 @@ std::string ElideHeaderValueForNetLog(NetLogCaptureMode capture_mode,
// Note: this logic should be kept in sync with stripCookiesAndLoginInfo in
// chrome/browser/resources/net_internals/log_view_painter.js.
- if (!base::strcasecmp(header.c_str(), "set-cookie") ||
- !base::strcasecmp(header.c_str(), "set-cookie2") ||
- !base::strcasecmp(header.c_str(), "cookie") ||
- !base::strcasecmp(header.c_str(), "authorization") ||
- !base::strcasecmp(header.c_str(), "proxy-authorization")) {
+ if (base::EqualsCaseInsensitiveASCII(header, "set-cookie") ||
+ base::EqualsCaseInsensitiveASCII(header, "set-cookie2") ||
+ base::EqualsCaseInsensitiveASCII(header, "cookie") ||
+ base::EqualsCaseInsensitiveASCII(header, "authorization") ||
+ base::EqualsCaseInsensitiveASCII(header, "proxy-authorization")) {
redact_begin = value.begin();
redact_end = value.end();
- } else if (!base::strcasecmp(header.c_str(), "www-authenticate") ||
- !base::strcasecmp(header.c_str(), "proxy-authenticate")) {
+ } else if (base::EqualsCaseInsensitiveASCII(header, "www-authenticate") ||
+ base::EqualsCaseInsensitiveASCII(header, "proxy-authenticate")) {
// Look for authentication information from data received from the server
// in multi-round Negotiate authentication.
HttpAuthChallengeTokenizer challenge(value.begin(), value.end());
diff --git a/chromium/net/http/http_network_layer.cc b/chromium/net/http/http_network_layer.cc
index e0b3199bb89..8e6b35cb25e 100644
--- a/chromium/net/http/http_network_layer.cc
+++ b/chromium/net/http/http_network_layer.cc
@@ -38,14 +38,6 @@ HttpNetworkLayer::~HttpNetworkLayer() {
#endif
}
-// static
-HttpTransactionFactory* HttpNetworkLayer::CreateFactory(
- HttpNetworkSession* session) {
- DCHECK(session);
-
- return new HttpNetworkLayer(session);
-}
-
int HttpNetworkLayer::CreateTransaction(RequestPriority priority,
scoped_ptr<HttpTransaction>* trans) {
if (suspended_)
diff --git a/chromium/net/http/http_network_layer.h b/chromium/net/http/http_network_layer.h
index 23b4e1eb2db..5ade926c3bd 100644
--- a/chromium/net/http/http_network_layer.h
+++ b/chromium/net/http/http_network_layer.h
@@ -30,14 +30,6 @@ class NET_EXPORT HttpNetworkLayer
explicit HttpNetworkLayer(HttpNetworkSession* session);
~HttpNetworkLayer() override;
- // Create a transaction factory that instantiate a network layer over an
- // existing network session. Network session contains some valuable
- // information (e.g. authentication data) that we want to share across
- // multiple network layers. This method exposes the implementation details
- // of a network layer, use this method with an existing network layer only
- // when network session is shared.
- static HttpTransactionFactory* CreateFactory(HttpNetworkSession* session);
-
// HttpTransactionFactory methods:
int CreateTransaction(RequestPriority priority,
scoped_ptr<HttpTransaction>* trans) override;
diff --git a/chromium/net/http/http_network_layer_unittest.cc b/chromium/net/http/http_network_layer_unittest.cc
index 9128cdd3da8..153423e45ff 100644
--- a/chromium/net/http/http_network_layer_unittest.cc
+++ b/chromium/net/http/http_network_layer_unittest.cc
@@ -32,10 +32,10 @@ class HttpNetworkLayerTest : public PlatformTest {
ConfigureTestDependencies(ProxyService::CreateDirect());
}
- void ConfigureTestDependencies(ProxyService* proxy_service) {
+ void ConfigureTestDependencies(scoped_ptr<ProxyService> proxy_service) {
cert_verifier_.reset(new MockCertVerifier);
transport_security_state_.reset(new TransportSecurityState);
- proxy_service_.reset(proxy_service);
+ proxy_service_ = proxy_service.Pass();
HttpNetworkSession::Params session_params;
session_params.client_socket_factory = &mock_socket_factory_;
session_params.host_resolver = &host_resolver_;
diff --git a/chromium/net/http/http_network_session.cc b/chromium/net/http/http_network_session.cc
index 950a0281bda..4c0009cd15f 100644
--- a/chromium/net/http/http_network_session.cc
+++ b/chromium/net/http/http_network_session.cc
@@ -79,6 +79,7 @@ HttpNetworkSession::Params::Params()
network_delegate(NULL),
net_log(NULL),
host_mapping_rules(NULL),
+ socket_performance_watcher_factory(NULL),
ignore_certificate_errors(false),
testing_fixed_http_port(0),
testing_fixed_https_port(0),
@@ -90,10 +91,10 @@ HttpNetworkSession::Params::Params()
spdy_stream_max_recv_window_size(kSpdyStreamMaxRecvWindowSize),
spdy_initial_max_concurrent_streams(0),
time_func(&base::TimeTicks::Now),
- use_alternate_protocols(false),
+ use_alternative_services(false),
alternative_service_probability_threshold(1),
enable_quic(false),
- disable_insecure_quic(false),
+ enable_insecure_quic(false),
enable_quic_for_proxies(false),
enable_quic_port_selection(true),
quic_always_require_handshake_confirmation(false),
@@ -103,9 +104,10 @@ HttpNetworkSession::Params::Params()
quic_enable_non_blocking_io(false),
quic_disable_disk_cache(false),
quic_prefer_aes(false),
- quic_max_number_of_lossy_connections(0),
- quic_packet_loss_threshold(1.0f),
+ quic_max_number_of_lossy_connections(4),
+ quic_packet_loss_threshold(0.5f),
quic_socket_receive_buffer_size(kQuicSocketReceiveBufferSize),
+ quic_delay_tcp_race(false),
quic_clock(NULL),
quic_random(NULL),
quic_max_packet_length(kDefaultMaxPacketSize),
@@ -140,8 +142,10 @@ HttpNetworkSession::HttpNetworkSession(const Params& params)
: ClientSocketFactory::GetDefaultFactory(),
params.http_server_properties,
params.cert_verifier,
+ params.cert_policy_enforcer,
params.channel_id_service,
params.transport_security_state,
+ params.socket_performance_watcher_factory,
params.quic_crypto_client_stream_factory,
params.quic_random ? params.quic_random : QuicRandom::GetInstance(),
params.quic_clock ? params.quic_clock : new QuicClock(),
@@ -162,6 +166,7 @@ HttpNetworkSession::HttpNetworkSession(const Params& params)
params.quic_threshold_public_resets_post_handshake,
params.quic_threshold_timeouts_streams_open,
params.quic_socket_receive_buffer_size,
+ params.quic_delay_tcp_race,
params.quic_connection_options),
spdy_session_pool_(params.host_resolver,
params.ssl_config_service,
diff --git a/chromium/net/http/http_network_session.h b/chromium/net/http/http_network_session.h
index d67182b1cef..c0503c9f73c 100644
--- a/chromium/net/http/http_network_session.h
+++ b/chromium/net/http/http_network_session.h
@@ -48,6 +48,7 @@ class ProxyService;
class QuicClock;
class QuicCryptoClientStreamFactory;
class QuicServerInfoFactory;
+class SocketPerformanceWatcherFactory;
class SOCKSClientSocketPool;
class SSLClientSocketPool;
class SSLConfigService;
@@ -78,6 +79,7 @@ class NET_EXPORT HttpNetworkSession
base::WeakPtr<HttpServerProperties> http_server_properties;
NetLog* net_log;
HostMappingRules* host_mapping_rules;
+ SocketPerformanceWatcherFactory* socket_performance_watcher_factory;
bool ignore_certificate_errors;
uint16 testing_fixed_http_port;
uint16 testing_fixed_https_port;
@@ -99,13 +101,11 @@ class NET_EXPORT HttpNetworkSession
std::string trusted_spdy_proxy;
// URLs to exclude from forced SPDY.
std::set<HostPortPair> forced_spdy_exclusions;
- // Noe: Using this in the case of NPN for HTTP only results in the browser
- // trying SSL and then falling back to http.
- bool use_alternate_protocols;
+ bool use_alternative_services;
double alternative_service_probability_threshold;
bool enable_quic;
- bool disable_insecure_quic;
+ bool enable_insecure_quic;
bool enable_quic_for_proxies;
bool enable_quic_port_selection;
bool quic_always_require_handshake_confirmation;
@@ -118,6 +118,7 @@ class NET_EXPORT HttpNetworkSession
int quic_max_number_of_lossy_connections;
float quic_packet_loss_threshold;
int quic_socket_receive_buffer_size;
+ bool quic_delay_tcp_race;
HostPortPair origin_to_force_quic_on;
QuicClock* quic_clock; // Will be owned by QuicStreamFactory.
QuicRandom* quic_random;
diff --git a/chromium/net/http/http_network_transaction.cc b/chromium/net/http/http_network_transaction.cc
index 76e352eed92..c12f95dfa67 100644
--- a/chromium/net/http/http_network_transaction.cc
+++ b/chromium/net/http/http_network_transaction.cc
@@ -67,10 +67,21 @@ namespace net {
namespace {
-void ProcessAlternateProtocol(
- HttpNetworkSession* session,
- const HttpResponseHeaders& headers,
- const HostPortPair& http_host_port_pair) {
+void ProcessAlternativeServices(HttpNetworkSession* session,
+ const HttpResponseHeaders& headers,
+ const HostPortPair& http_host_port_pair) {
+ if (session->params().use_alternative_services &&
+ headers.HasHeader(kAlternativeServiceHeader)) {
+ std::string alternative_service_str;
+ headers.GetNormalizedHeader(kAlternativeServiceHeader,
+ &alternative_service_str);
+ session->http_stream_factory()->ProcessAlternativeService(
+ session->http_server_properties(), alternative_service_str,
+ http_host_port_pair, *session);
+ // If there is an "Alt-Svc" header, then ignore "Alternate-Protocol".
+ return;
+ }
+
if (!headers.HasHeader(kAlternateProtocolHeader))
return;
@@ -138,6 +149,7 @@ HttpNetworkTransaction::HttpNetworkTransaction(RequestPriority priority,
request_headers_(),
read_buf_len_(0),
total_received_bytes_(0),
+ total_sent_bytes_(0),
next_state_(STATE_NONE),
establishing_tunnel_(false),
websocket_handshake_stream_base_create_helper_(NULL) {
@@ -148,28 +160,18 @@ HttpNetworkTransaction::HttpNetworkTransaction(RequestPriority priority,
HttpNetworkTransaction::~HttpNetworkTransaction() {
if (stream_.get()) {
- HttpResponseHeaders* headers = GetResponseHeaders();
// TODO(mbelshe): The stream_ should be able to compute whether or not the
// stream should be kept alive. No reason to compute here
// and pass it in.
- bool try_to_keep_alive =
- next_state_ == STATE_NONE &&
- stream_->CanFindEndOfResponse() &&
- (!headers || headers->IsKeepAlive());
- if (!try_to_keep_alive) {
+ if (!stream_->CanReuseConnection() || next_state_ != STATE_NONE) {
stream_->Close(true /* not reusable */);
+ } else if (stream_->IsResponseBodyComplete()) {
+ // If the response body is complete, we can just reuse the socket.
+ stream_->Close(false /* reusable */);
} else {
- if (stream_->IsResponseBodyComplete()) {
- // If the response body is complete, we can just reuse the socket.
- stream_->Close(false /* reusable */);
- } else if (stream_->IsSpdyHttpStream()) {
- // Doesn't really matter for SpdyHttpStream. Just close it.
- stream_->Close(true /* not reusable */);
- } else {
- // Otherwise, we try to drain the response body.
- HttpStream* stream = stream_.release();
- stream->Drain(session_);
- }
+ // Otherwise, we try to drain the response body.
+ HttpStream* stream = stream_.release();
+ stream->Drain(session_);
}
}
@@ -195,12 +197,6 @@ int HttpNetworkTransaction::Start(const HttpRequestInfo* request_info,
if (request_->privacy_mode == PRIVACY_MODE_ENABLED)
server_ssl_config_.channel_id_enabled = false;
- if (server_ssl_config_.fastradio_padding_enabled) {
- server_ssl_config_.fastradio_padding_eligible =
- session_->ssl_config_service()->SupportsFastradioPadding(
- request_info->url);
- }
-
next_state_ = STATE_NOTIFY_BEFORE_CREATE_STREAM;
int rv = DoLoop(OK);
if (rv == ERR_IO_PENDING)
@@ -288,8 +284,7 @@ void HttpNetworkTransaction::PrepareForAuthRestart(HttpAuth::Target target) {
bool keep_alive = false;
// Even if the server says the connection is keep-alive, we have to be
// able to find the end of each response in order to reuse the connection.
- if (GetResponseHeaders()->IsKeepAlive() &&
- stream_->CanFindEndOfResponse()) {
+ if (stream_->CanReuseConnection()) {
// If the response body hasn't been completely read, we need to drain
// it first.
if (!stream_->IsResponseBodyComplete()) {
@@ -311,8 +306,9 @@ void HttpNetworkTransaction::DidDrainBodyForAuthRestart(bool keep_alive) {
if (stream_.get()) {
total_received_bytes_ += stream_->GetTotalReceivedBytes();
+ total_sent_bytes_ += stream_->GetTotalSentBytes();
HttpStream* new_stream = NULL;
- if (keep_alive && stream_->IsConnectionReusable()) {
+ if (keep_alive && stream_->CanReuseConnection()) {
// We should call connection_->set_idle_time(), but this doesn't occur
// often enough to be worth the trouble.
stream_->SetConnectionReused();
@@ -326,8 +322,9 @@ void HttpNetworkTransaction::DidDrainBodyForAuthRestart(bool keep_alive) {
stream_->Close(true);
next_state_ = STATE_CREATE_STREAM;
} else {
- // Renewed streams shouldn't carry over received bytes.
+ // Renewed streams shouldn't carry over sent or received bytes.
DCHECK_EQ(0, new_stream->GetTotalReceivedBytes());
+ DCHECK_EQ(0, new_stream->GetTotalSentBytes());
next_state_ = STATE_INIT_STREAM;
}
stream_.reset(new_stream);
@@ -390,13 +387,20 @@ bool HttpNetworkTransaction::GetFullRequestHeaders(
return true;
}
-int64 HttpNetworkTransaction::GetTotalReceivedBytes() const {
- int64 total_received_bytes = total_received_bytes_;
+int64_t HttpNetworkTransaction::GetTotalReceivedBytes() const {
+ int64_t total_received_bytes = total_received_bytes_;
if (stream_)
total_received_bytes += stream_->GetTotalReceivedBytes();
return total_received_bytes;
}
+int64_t HttpNetworkTransaction::GetTotalSentBytes() const {
+ int64_t total_sent_bytes = total_sent_bytes_;
+ if (stream_)
+ total_sent_bytes += stream_->GetTotalSentBytes();
+ return total_sent_bytes;
+}
+
void HttpNetworkTransaction::DoneReading() {}
const HttpResponseInfo* HttpNetworkTransaction::GetResponseInfo() const {
@@ -447,6 +451,14 @@ bool HttpNetworkTransaction::GetLoadTimingInfo(
return true;
}
+bool HttpNetworkTransaction::GetRemoteEndpoint(IPEndPoint* endpoint) const {
+ if (!remote_endpoint_.address().size())
+ return false;
+
+ *endpoint = remote_endpoint_;
+ return true;
+}
+
void HttpNetworkTransaction::SetPriority(RequestPriority priority) {
priority_ = priority;
if (stream_request_)
@@ -481,8 +493,10 @@ void HttpNetworkTransaction::OnStreamReady(const SSLConfig& used_ssl_config,
DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_);
DCHECK(stream_request_.get());
- if (stream_)
+ if (stream_) {
total_received_bytes_ += stream_->GetTotalReceivedBytes();
+ total_sent_bytes_ += stream_->GetTotalSentBytes();
+ }
stream_.reset(stream);
server_ssl_config_ = used_ssl_config;
proxy_info_ = used_proxy_info;
@@ -581,8 +595,10 @@ void HttpNetworkTransaction::OnHttpsProxyTunnelResponse(
response_ = response_info;
server_ssl_config_ = used_ssl_config;
proxy_info_ = used_proxy_info;
- if (stream_)
+ if (stream_) {
total_received_bytes_ += stream_->GetTotalReceivedBytes();
+ total_sent_bytes_ += stream_->GetTotalSentBytes();
+ }
stream_.reset(stream);
stream_request_.reset(); // we're done with the stream request
OnIOComplete(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
@@ -805,6 +821,9 @@ int HttpNetworkTransaction::DoCreateStreamComplete(int result) {
int HttpNetworkTransaction::DoInitStream() {
DCHECK(stream_.get());
next_state_ = STATE_INIT_STREAM_COMPLETE;
+
+ stream_->GetRemoteEndpoint(&remote_endpoint_);
+
return stream_->InitializeStream(request_, priority_, net_log_, io_callback_);
}
@@ -816,8 +835,10 @@ int HttpNetworkTransaction::DoInitStreamComplete(int result) {
result = HandleIOError(result);
// The stream initialization failed, so this stream will never be useful.
- if (stream_)
- total_received_bytes_ += stream_->GetTotalReceivedBytes();
+ if (stream_) {
+ total_received_bytes_ += stream_->GetTotalReceivedBytes();
+ total_sent_bytes_ += stream_->GetTotalSentBytes();
+ }
stream_.reset();
}
@@ -896,12 +917,13 @@ void HttpNetworkTransaction::BuildRequestHeaders(
HttpRequestHeaders::kContentLength,
base::Uint64ToString(request_->upload_data_stream->size()));
}
- } else if (request_->method == "POST" || request_->method == "PUT" ||
- request_->method == "HEAD") {
+ } else if (request_->method == "POST" || request_->method == "PUT") {
// An empty POST/PUT request still needs a content length. As for HEAD,
// IE and Safari also add a content length header. Presumably it is to
// support sending a HEAD request to an URL that only expects to be sent a
// POST or some other method that normally would have a message body.
+ // Firefox (40.0) does not send the header, and RFC 7230 & 7231
+ // specify that it should not be sent due to undefined behavior.
request_headers_.SetHeader(HttpRequestHeaders::kContentLength, "0");
}
@@ -1077,8 +1099,8 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) {
return OK;
}
- ProcessAlternateProtocol(session_, *response_.headers.get(),
- HostPortPair::FromURL(request_->url));
+ ProcessAlternativeServices(session_, *response_.headers.get(),
+ HostPortPair::FromURL(request_->url));
int rv = HandleAuthChallenge();
if (rv != OK)
@@ -1109,26 +1131,18 @@ int HttpNetworkTransaction::DoReadBodyComplete(int result) {
done = true;
}
- bool keep_alive = false;
- if (stream_->IsResponseBodyComplete()) {
+ // Clean up connection if we are done.
+ if (done) {
// Note: Just because IsResponseBodyComplete is true, we're not
// necessarily "done". We're only "done" when it is the last
// read on this HttpNetworkTransaction, which will be signified
// by a zero-length read.
- // TODO(mbelshe): The keepalive property is really a property of
+ // TODO(mbelshe): The keep-alive property is really a property of
// the stream. No need to compute it here just to pass back
// to the stream's Close function.
- // TODO(rtenneti): CanFindEndOfResponse should return false if there are no
- // ResponseHeaders.
- if (stream_->CanFindEndOfResponse()) {
- HttpResponseHeaders* headers = GetResponseHeaders();
- if (headers)
- keep_alive = headers->IsKeepAlive();
- }
- }
+ bool keep_alive =
+ stream_->IsResponseBodyComplete() && stream_->CanReuseConnection();
- // Clean up connection if we are done.
- if (done) {
stream_->Close(!keep_alive);
// Note: we don't reset the stream here. We've closed it, but we still
// need it around so that callers can call methods such as
@@ -1198,6 +1212,7 @@ int HttpNetworkTransaction::HandleCertificateRequest(int error) {
// renegotiation.
DCHECK(!stream_request_.get());
total_received_bytes_ += stream_->GetTotalReceivedBytes();
+ total_sent_bytes_ += stream_->GetTotalSentBytes();
stream_->Close(true);
stream_.reset();
}
@@ -1421,8 +1436,10 @@ int HttpNetworkTransaction::HandleIOError(int error) {
void HttpNetworkTransaction::ResetStateForRestart() {
ResetStateForAuthRestart();
- if (stream_)
+ if (stream_) {
total_received_bytes_ += stream_->GetTotalReceivedBytes();
+ total_sent_bytes_ += stream_->GetTotalSentBytes();
+ }
stream_.reset();
}
@@ -1437,6 +1454,7 @@ void HttpNetworkTransaction::ResetStateForAuthRestart() {
request_headers_.Clear();
response_ = HttpResponseInfo();
establishing_tunnel_ = false;
+ remote_endpoint_ = IPEndPoint();
}
void HttpNetworkTransaction::RecordSSLFallbackMetrics(int result) {
@@ -1444,7 +1462,8 @@ void HttpNetworkTransaction::RecordSSLFallbackMetrics(int result) {
return;
const std::string& host = request_->url.host();
- bool is_google = base::EndsWith(host, "google.com", true) &&
+ bool is_google = base::EndsWith(host, "google.com",
+ base::CompareCase::SENSITIVE) &&
(host.size() == 10 || host[host.size() - 11] == '.');
if (is_google) {
// Some fraction of successful connections use the fallback, but only due to
diff --git a/chromium/net/http/http_network_transaction.h b/chromium/net/http/http_network_transaction.h
index ed4597d94fa..a5e5b080323 100644
--- a/chromium/net/http/http_network_transaction.h
+++ b/chromium/net/http/http_network_transaction.h
@@ -5,6 +5,8 @@
#ifndef NET_HTTP_HTTP_NETWORK_TRANSACTION_H_
#define NET_HTTP_HTTP_NETWORK_TRANSACTION_H_
+#include <stdint.h>
+
#include <string>
#include "base/basictypes.h"
@@ -62,13 +64,15 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
const CompletionCallback& callback) override;
void StopCaching() override;
bool GetFullRequestHeaders(HttpRequestHeaders* headers) const override;
- int64 GetTotalReceivedBytes() const override;
+ int64_t GetTotalReceivedBytes() const override;
+ int64_t GetTotalSentBytes() const override;
void DoneReading() override;
const HttpResponseInfo* GetResponseInfo() const override;
LoadState GetLoadState() const override;
UploadProgress GetUploadProgress() const override;
void SetQuicServerInfo(QuicServerInfo* quic_server_info) override;
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
+ bool GetRemoteEndpoint(IPEndPoint* endpoint) const override;
void SetPriority(RequestPriority priority) override;
void SetWebSocketHandshakeStreamCreateHelper(
WebSocketHandshakeStreamBase::CreateHelper* create_helper) override;
@@ -319,8 +323,13 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
scoped_refptr<IOBuffer> read_buf_;
int read_buf_len_;
- // Total number of bytes received on streams for this transaction.
- int64 total_received_bytes_;
+ // Total number of bytes received on all destroyed HttpStreams for this
+ // transaction.
+ int64_t total_received_bytes_;
+
+ // Total number of bytes sent on all destroyed HttpStreams for this
+ // transaction.
+ int64_t total_sent_bytes_;
// When the transaction started / finished sending the request, including
// the body, if present.
@@ -343,6 +352,7 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
BeforeProxyHeadersSentCallback before_proxy_headers_sent_callback_;
ConnectionAttempts connection_attempts_;
+ IPEndPoint remote_endpoint_;
DISALLOW_COPY_AND_ASSIGN(HttpNetworkTransaction);
};
diff --git a/chromium/net/http/http_network_transaction_ssl_unittest.cc b/chromium/net/http/http_network_transaction_ssl_unittest.cc
index 2db5a9997c9..da28d9cd74d 100644
--- a/chromium/net/http/http_network_transaction_ssl_unittest.cc
+++ b/chromium/net/http/http_network_transaction_ssl_unittest.cc
@@ -65,7 +65,7 @@ class HttpNetworkTransactionSSLTest : public testing::Test {
auth_handler_factory_.reset(new HttpAuthHandlerMock::Factory());
session_params_.http_auth_handler_factory = auth_handler_factory_.get();
- proxy_service_.reset(ProxyService::CreateDirect());
+ proxy_service_ = ProxyService::CreateDirect();
session_params_.proxy_service = proxy_service_.get();
session_params_.client_socket_factory = &mock_socket_factory_;
diff --git a/chromium/net/http/http_network_transaction_unittest.cc b/chromium/net/http/http_network_transaction_unittest.cc
index 1813c809ea5..fb65846782a 100644
--- a/chromium/net/http/http_network_transaction_unittest.cc
+++ b/chromium/net/http/http_network_transaction_unittest.cc
@@ -6,6 +6,8 @@
#include <math.h> // ceil
#include <stdarg.h>
+#include <stdint.h>
+
#include <string>
#include <vector>
@@ -263,9 +265,11 @@ class HttpNetworkTransactionTest
int rv;
std::string status_line;
std::string response_data;
- int64 totalReceivedBytes;
+ int64_t total_received_bytes;
+ int64_t total_sent_bytes;
LoadTimingInfo load_timing_info;
ConnectionAttempts connection_attempts;
+ IPEndPoint remote_endpoint_after_start;
};
void SetUp() override {
@@ -288,10 +292,14 @@ class HttpNetworkTransactionTest
AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam()));
}
- // This is the expected return from a current server advertising SPDY.
+ std::string GetAlternativeServiceHttpHeader() {
+ return std::string("Alt-Svc: ") + GetAlternateProtocolFromParam() +
+ "=\"www.example.com:443\"\r\n";
+ }
+
std::string GetAlternateProtocolHttpHeader() {
return std::string("Alternate-Protocol: 443:") +
- GetAlternateProtocolFromParam() + "\r\n\r\n";
+ GetAlternateProtocolFromParam() + "\r\n";
}
// Either |write_failure| specifies a write failure or |read_failure|
@@ -335,6 +343,8 @@ class HttpNetworkTransactionTest
EXPECT_EQ(ERR_IO_PENDING, rv);
out.rv = callback.WaitForResult();
+ out.total_received_bytes = trans->GetTotalReceivedBytes();
+ out.total_sent_bytes = trans->GetTotalSentBytes();
// Even in the failure cases that use this function, connections are always
// successfully established before the error.
@@ -356,6 +366,11 @@ class HttpNetworkTransactionTest
EXPECT_EQ("127.0.0.1", response->socket_address.host());
EXPECT_EQ(80, response->socket_address.port());
+ bool got_endpoint =
+ trans->GetRemoteEndpoint(&out.remote_endpoint_after_start);
+ EXPECT_EQ(got_endpoint,
+ out.remote_endpoint_after_start.address().size() > 0);
+
rv = ReadTransaction(trans.get(), &out.response_data);
EXPECT_EQ(OK, rv);
@@ -386,23 +401,30 @@ class HttpNetworkTransactionTest
EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
response_headers);
- out.totalReceivedBytes = trans->GetTotalReceivedBytes();
+ out.total_received_bytes = trans->GetTotalReceivedBytes();
+ // The total number of sent bytes should not have changed.
+ EXPECT_EQ(out.total_sent_bytes, trans->GetTotalSentBytes());
+
trans->GetConnectionAttempts(&out.connection_attempts);
return out;
}
SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
size_t reads_count) {
- StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
- StaticSocketDataProvider* data[] = { &reads };
- return SimpleGetHelperForData(data, 1);
- }
+ MockWrite data_writes[] = {
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
+ };
- int64 ReadsSize(MockRead data_reads[], size_t reads_count) {
- int64 size = 0;
- for (size_t i = 0; i < reads_count; ++i)
- size += data_reads[i].data_len;
- return size;
+ StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
+ arraysize(data_writes));
+ StaticSocketDataProvider* data[] = {&reads};
+ SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
+
+ EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
+ out.total_sent_bytes);
+ return out;
}
void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
@@ -426,7 +448,6 @@ class HttpNetworkTransactionTest
INSTANTIATE_TEST_CASE_P(NextProto,
HttpNetworkTransactionTest,
testing::Values(kProtoSPDY31,
- kProtoHTTP2_14,
kProtoHTTP2));
namespace {
@@ -494,6 +515,7 @@ void FillLargeHeadersString(std::string* str, int size) {
str->append(row, sizeof_row);
}
+#if defined(NTLM_PORTABLE)
// Alternative functions that eliminate randomness and dependency on the local
// host name so that the generated NTLM messages are reproducible.
void MockGenerateRandom1(uint8* output, size_t n) {
@@ -522,6 +544,7 @@ void MockGenerateRandom2(uint8* output, size_t n) {
std::string MockGetHostName() {
return "WTC-WIN7";
}
+#endif // defined(NTLM_PORTABLE)
template<typename ParentPool>
class CaptureGroupNameSocketPool : public ParentPool {
@@ -641,6 +664,7 @@ bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
return true;
}
+#if defined(NTLM_PORTABLE)
bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
if (!auth_challenge)
return false;
@@ -650,6 +674,7 @@ bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
EXPECT_EQ("ntlm", auth_challenge->scheme);
return true;
}
+#endif // defined(NTLM_PORTABLE)
} // namespace
@@ -670,9 +695,11 @@ TEST_P(HttpNetworkTransactionTest, SimpleGET) {
EXPECT_EQ(OK, out.rv);
EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
EXPECT_EQ("hello world", out.response_data);
- int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
- EXPECT_EQ(reads_size, out.totalReceivedBytes);
+ int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
+ EXPECT_EQ(reads_size, out.total_received_bytes);
EXPECT_EQ(0u, out.connection_attempts.size());
+
+ EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
}
// Response with no status line.
@@ -686,8 +713,8 @@ TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
EXPECT_EQ(OK, out.rv);
EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
EXPECT_EQ("hello world", out.response_data);
- int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
- EXPECT_EQ(reads_size, out.totalReceivedBytes);
+ int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
+ EXPECT_EQ(reads_size, out.total_received_bytes);
}
// Allow up to 4 bytes of junk to precede status line.
@@ -701,8 +728,8 @@ TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
EXPECT_EQ(OK, out.rv);
EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
EXPECT_EQ("DATA", out.response_data);
- int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
- EXPECT_EQ(reads_size, out.totalReceivedBytes);
+ int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
+ EXPECT_EQ(reads_size, out.total_received_bytes);
}
// Allow up to 4 bytes of junk to precede status line.
@@ -716,8 +743,8 @@ TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
EXPECT_EQ(OK, out.rv);
EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
EXPECT_EQ("DATA", out.response_data);
- int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
- EXPECT_EQ(reads_size, out.totalReceivedBytes);
+ int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
+ EXPECT_EQ(reads_size, out.total_received_bytes);
}
// Beyond 4 bytes of slop and it should fail to find a status line.
@@ -731,8 +758,8 @@ TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
EXPECT_EQ(OK, out.rv);
EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
- int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
- EXPECT_EQ(reads_size, out.totalReceivedBytes);
+ int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
+ EXPECT_EQ(reads_size, out.total_received_bytes);
}
// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
@@ -750,8 +777,8 @@ TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
EXPECT_EQ(OK, out.rv);
EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
EXPECT_EQ("DATA", out.response_data);
- int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
- EXPECT_EQ(reads_size, out.totalReceivedBytes);
+ int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
+ EXPECT_EQ(reads_size, out.total_received_bytes);
}
// Close the connection before enough bytes to have a status line.
@@ -765,8 +792,8 @@ TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
EXPECT_EQ(OK, out.rv);
EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
EXPECT_EQ("HTT", out.response_data);
- int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
- EXPECT_EQ(reads_size, out.totalReceivedBytes);
+ int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
+ EXPECT_EQ(reads_size, out.total_received_bytes);
}
// Simulate a 204 response, lacking a Content-Length header, sent over a
@@ -784,9 +811,9 @@ TEST_P(HttpNetworkTransactionTest, StopsReading204) {
EXPECT_EQ(OK, out.rv);
EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
EXPECT_EQ("", out.response_data);
- int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
- int64 response_size = reads_size - strlen(junk);
- EXPECT_EQ(response_size, out.totalReceivedBytes);
+ int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
+ int64_t response_size = reads_size - strlen(junk);
+ EXPECT_EQ(response_size, out.total_received_bytes);
}
// A simple request using chunked encoding with some extra data after.
@@ -808,9 +835,9 @@ TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
EXPECT_EQ(OK, out.rv);
EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
EXPECT_EQ("Hello world", out.response_data);
- int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
- int64 response_size = reads_size - extra_data.size();
- EXPECT_EQ(response_size, out.totalReceivedBytes);
+ int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
+ int64_t response_size = reads_size - extra_data.size();
+ EXPECT_EQ(response_size, out.total_received_bytes);
}
// Next tests deal with http://crbug.com/56344.
@@ -1027,11 +1054,9 @@ TEST_P(HttpNetworkTransactionTest, Head) {
base::Unretained(&proxy_headers_handler)));
MockWrite data_writes1[] = {
- MockWrite(
- "HEAD / HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n"
- "Content-Length: 0\r\n\r\n"),
+ MockWrite("HEAD / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
};
MockRead data_reads1[] = {
MockRead("HTTP/1.1 404 Not Found\r\n"),
@@ -1441,8 +1466,8 @@ void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
SSLConfig ssl_config;
session->ssl_config_service()->GetSSLConfig(&ssl_config);
session->GetNextProtos(&ssl_config.next_protos);
- session->http_stream_factory()->PreconnectStreams(
- 1, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
+ session->http_stream_factory()->PreconnectStreams(1, request, ssl_config,
+ ssl_config);
// Wait for the preconnect to complete.
// TODO(davidben): Some way to wait for an idle socket count might be handy.
base::RunLoop().RunUntilIdle();
@@ -1585,6 +1610,10 @@ TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
rv = callback.WaitForResult();
EXPECT_EQ(ERR_CONNECTION_RESET, rv);
+
+ IPEndPoint endpoint;
+ EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
+ EXPECT_LT(0u, endpoint.address().size());
}
// What do various browsers do when the server closes a non-keepalive
@@ -1948,7 +1977,9 @@ TEST_P(HttpNetworkTransactionTest, BasicAuth) {
EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
- int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
+ int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
+ EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
+ int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
const HttpResponseInfo* response = trans->GetResponseInfo();
@@ -1973,7 +2004,9 @@ TEST_P(HttpNetworkTransactionTest, BasicAuth) {
load_timing_info2.connect_timing.connect_start);
EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
- int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
+ int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
+ EXPECT_EQ(writes_size1 + writes_size2, trans->GetTotalSentBytes());
+ int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
response = trans->GetResponseInfo();
@@ -1982,6 +2015,122 @@ TEST_P(HttpNetworkTransactionTest, BasicAuth) {
EXPECT_EQ(100, response->headers->GetContentLength());
}
+// Test the request-challenge-retry sequence for basic auth.
+// (basic auth is the easiest to mock, because it has no randomness).
+TEST_P(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://www.example.org/");
+ request.load_flags = 0;
+
+ TestNetLog log;
+ MockHostResolver* resolver = new MockHostResolver();
+ session_deps_.net_log = &log;
+ session_deps_.host_resolver.reset(resolver);
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+
+ resolver->rules()->ClearRules();
+ resolver->rules()->AddRule("www.example.org", "127.0.0.1");
+
+ MockWrite data_writes1[] = {
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
+ };
+
+ MockRead data_reads1[] = {
+ MockRead("HTTP/1.0 401 Unauthorized\r\n"),
+ // Give a couple authenticate options (only the middle one is actually
+ // supported).
+ MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
+ MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
+ MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
+ MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
+ // Large content-length -- won't matter, as connection will be reset.
+ MockRead("Content-Length: 10000\r\n\r\n"),
+ MockRead(SYNCHRONOUS, ERR_FAILED),
+ };
+
+ // After calling trans->RestartWithAuth(), this is the request we should
+ // be issuing -- the final header line contains the credentials.
+ MockWrite data_writes2[] = {
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n"
+ "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
+ };
+
+ // Lastly, the server responds with the actual content.
+ MockRead data_reads2[] = {
+ MockRead("HTTP/1.0 200 OK\r\n"),
+ MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
+ MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
+ };
+
+ StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
+ data_writes1, arraysize(data_writes1));
+ StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
+ data_writes2, arraysize(data_writes2));
+ session_deps_.socket_factory->AddSocketDataProvider(&data1);
+ session_deps_.socket_factory->AddSocketDataProvider(&data2);
+
+ TestCompletionCallback callback1;
+
+ EXPECT_EQ(OK, callback1.GetResult(trans->Start(&request, callback1.callback(),
+ BoundNetLog())));
+
+ LoadTimingInfo load_timing_info1;
+ EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
+ TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
+
+ int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
+ EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
+ int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
+ EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
+
+ const HttpResponseInfo* response = trans->GetResponseInfo();
+ ASSERT_TRUE(response);
+ EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
+
+ IPEndPoint endpoint;
+ EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
+ ASSERT_FALSE(endpoint.address().empty());
+ EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
+
+ resolver->rules()->ClearRules();
+ resolver->rules()->AddRule("www.example.org", "127.0.0.2");
+
+ TestCompletionCallback callback2;
+
+ EXPECT_EQ(OK, callback2.GetResult(trans->RestartWithAuth(
+ AuthCredentials(kFoo, kBar), callback2.callback())));
+
+ LoadTimingInfo load_timing_info2;
+ EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
+ TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
+ // The load timing after restart should have a new socket ID, and times after
+ // those of the first load timing.
+ EXPECT_LE(load_timing_info1.receive_headers_end,
+ load_timing_info2.connect_timing.connect_start);
+ EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
+
+ int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
+ EXPECT_EQ(writes_size1 + writes_size2, trans->GetTotalSentBytes());
+ int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
+ EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
+
+ response = trans->GetResponseInfo();
+ ASSERT_TRUE(response);
+ EXPECT_FALSE(response->auth_challenge.get());
+ EXPECT_EQ(100, response->headers->GetContentLength());
+
+ EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
+ ASSERT_FALSE(endpoint.address().empty());
+ EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
+}
+
TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
HttpRequestInfo request;
request.method = "GET";
@@ -2019,7 +2168,9 @@ TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
rv = callback.WaitForResult();
EXPECT_EQ(0, rv);
- int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
+ int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
+ EXPECT_EQ(writes_size, trans->GetTotalSentBytes());
+ int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
const HttpResponseInfo* response = trans->GetResponseInfo();
@@ -2125,7 +2276,10 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
std::string response_data;
rv = ReadTransaction(trans.get(), &response_data);
EXPECT_EQ(OK, rv);
- int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
+
+ int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
+ EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
+ int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
}
@@ -2392,8 +2546,8 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
// Configure against proxy server "myproxy:70".
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
+ session_deps_.proxy_service =
+ ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -2510,8 +2664,8 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
// Configure against proxy server "myproxy:70".
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
+ session_deps_.proxy_service =
+ ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -2631,7 +2785,7 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
// Configure against proxy server "myproxy:70".
- session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -2738,7 +2892,7 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
// Configure against proxy server "myproxy:70".
- session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -2842,7 +2996,7 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
request.load_flags = 0;
// Configure against proxy server "myproxy:70".
- session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -2902,7 +3056,7 @@ TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
request.load_flags = 0;
// Configure against proxy server "myproxy:70".
- session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -3010,7 +3164,7 @@ TEST_P(HttpNetworkTransactionTest,
request.method = "GET";
request.url = GURL("https://www.example.org/");
- session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -3075,8 +3229,7 @@ TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
request2.url = GURL("https://www.example.org/2");
// Configure against proxy server "myproxy:70".
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixed("PROXY myproxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("PROXY myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -3176,8 +3329,8 @@ TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
request2.url = GURL("https://www.example.org/2");
// Configure against proxy server "myproxy:70".
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
+ session_deps_.proxy_service =
+ ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -3274,8 +3427,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
request.url = GURL("http://www.example.org/");
// Configure against https proxy server "proxy:70".
- session_deps_.proxy_service.reset(ProxyService::CreateFixed(
- "https://proxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -3337,8 +3489,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
request.load_flags = 0;
// Configure against https proxy server "proxy:70".
- session_deps_.proxy_service.reset(ProxyService::CreateFixed(
- "https://proxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -3398,8 +3549,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
request.load_flags = 0;
// Configure SPDY proxy server "proxy:70".
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixed("https://proxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -3468,8 +3618,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
request.load_flags = 0;
// Configure against https proxy server "myproxy:70".
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixed("https://myproxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -3569,8 +3718,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
request.load_flags = 0;
// Configure against https proxy server "proxy:70".
- session_deps_.proxy_service.reset(ProxyService::CreateFixed(
- "https://proxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -3654,8 +3802,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
request.load_flags = 0;
// Configure against https proxy server "proxy:70".
- session_deps_.proxy_service.reset(ProxyService::CreateFixed(
- "https://proxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -3746,8 +3893,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
request.load_flags = 0;
// Configure against https proxy server "proxy:70".
- session_deps_.proxy_service.reset(ProxyService::CreateFixed(
- "https://proxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -3798,8 +3944,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
TEST_P(HttpNetworkTransactionTest,
HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
// Configure against https proxy server "proxy:70".
- session_deps_.proxy_service.reset(ProxyService::CreateFixed(
- "https://proxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
scoped_refptr<HttpNetworkSession> session(
@@ -3839,10 +3984,14 @@ TEST_P(HttpNetworkTransactionTest,
// CONNECT to mail.example.org:443 via SPDY.
SpdyHeaderBlock connect2_block;
- connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
- connect2_block[spdy_util_.GetPathKey()] = "mail.example.org:443";
- connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
spdy_util_.MaybeAddVersionHeader(&connect2_block);
+ connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
+ if (GetParam() == kProtoHTTP2) {
+ connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
+ } else {
+ connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
+ connect2_block[spdy_util_.GetPathKey()] = "mail.example.org:443";
+ }
scoped_ptr<SpdyFrame> connect2(
spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
@@ -3937,8 +4086,7 @@ TEST_P(HttpNetworkTransactionTest,
TEST_P(HttpNetworkTransactionTest,
HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
// Configure against https proxy server "proxy:70".
- session_deps_.proxy_service.reset(ProxyService::CreateFixed(
- "https://proxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
scoped_refptr<HttpNetworkSession> session(
@@ -4061,8 +4209,7 @@ TEST_P(HttpNetworkTransactionTest,
// Proxy to different servers.
TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
// Configure against https proxy server "proxy:70".
- session_deps_.proxy_service.reset(ProxyService::CreateFixed(
- "https://proxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
scoped_refptr<HttpNetworkSession> session(
@@ -4168,8 +4315,7 @@ TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
// Configure against https proxy server "myproxy:70".
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixed("https://myproxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -4268,7 +4414,7 @@ void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
request.load_flags = 0;
// Configure against proxy server "myproxy:70".
- session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Since we have proxy, should try to establish tunnel.
@@ -4486,7 +4632,7 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
request.load_flags = 0;
// Configure against proxy server "myproxy:70".
- session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
@@ -4989,7 +5135,7 @@ TEST_P(HttpNetworkTransactionTest,
request.load_flags = 0;
// Configure against proxy server "myproxy:70".
- session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -6305,7 +6451,7 @@ TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
// Test HTTPS connections to a site with a bad certificate, going through a
// proxy
TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
- session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
HttpRequestInfo request;
request.method = "GET";
@@ -6387,8 +6533,8 @@ TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
// Test HTTPS connections to a site, going through an HTTPS proxy
TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
+ session_deps_.proxy_service =
+ ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
TestNetLog net_log;
session_deps_.net_log = &net_log;
@@ -6453,8 +6599,8 @@ TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
// Test an HTTPS Proxy's ability to redirect a CONNECT request
TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
+ session_deps_.proxy_service =
+ ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
TestNetLog net_log;
session_deps_.net_log = &net_log;
@@ -6530,8 +6676,7 @@ TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixed("https://proxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
HttpRequestInfo request;
request.method = "GET";
@@ -6590,8 +6735,7 @@ TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
// Test that an HTTPS proxy's response to a CONNECT request is filtered.
TEST_P(HttpNetworkTransactionTest,
ErrorResponseToHttpsConnectViaHttpsProxy) {
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixed("https://proxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
HttpRequestInfo request;
request.method = "GET";
@@ -6637,8 +6781,7 @@ TEST_P(HttpNetworkTransactionTest,
// Test that a SPDY proxy's response to a CONNECT request is filtered.
TEST_P(HttpNetworkTransactionTest,
ErrorResponseToHttpsConnectViaSpdyProxy) {
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixed("https://proxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
HttpRequestInfo request;
request.method = "GET";
@@ -6702,8 +6845,8 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
// Configure against https proxy server "myproxy:70".
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
+ session_deps_.proxy_service =
+ ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -6843,8 +6986,8 @@ TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
push_request.url = GURL("http://www.another-origin.com/foo.dat");
// Configure against https proxy server "myproxy:70".
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
+ session_deps_.proxy_service =
+ ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
@@ -6957,8 +7100,7 @@ TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
request.url = GURL("http://www.example.org/");
// Configure against https proxy server "myproxy:70".
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixed("https://myproxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
@@ -7033,8 +7175,7 @@ TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
// Test HTTPS connections to a site with a bad certificate, going through an
// HTTPS proxy
TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
- session_deps_.proxy_service.reset(ProxyService::CreateFixed(
- "https://proxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
HttpRequestInfo request;
request.method = "GET";
@@ -7163,7 +7304,7 @@ TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
"Chromium Ultra Awesome X Edition");
- session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -7323,11 +7464,9 @@ TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
MockWrite data_writes[] = {
- MockWrite(
- "HEAD / HTTP/1.1\r\n"
- "Host: www.example.org\r\n"
- "Connection: keep-alive\r\n"
- "Content-Length: 0\r\n\r\n"),
+ MockWrite("HEAD / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
};
// Lastly, the server responds with the actual content.
@@ -7519,8 +7658,8 @@ TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
request.url = GURL("http://www.example.org/");
request.load_flags = 0;
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
+ session_deps_.proxy_service =
+ ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
TestNetLog net_log;
session_deps_.net_log = &net_log;
@@ -7578,8 +7717,8 @@ TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
request.url = GURL("https://www.example.org/");
request.load_flags = 0;
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
+ session_deps_.proxy_service =
+ ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
TestNetLog net_log;
session_deps_.net_log = &net_log;
@@ -7642,8 +7781,8 @@ TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
request.url = GURL("http://www.example.org/");
request.load_flags = 0;
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixed("socks4://myproxy:1080"));
+ session_deps_.proxy_service =
+ ProxyService::CreateFixed("socks4://myproxy:1080");
TestNetLog net_log;
session_deps_.net_log = &net_log;
@@ -7701,8 +7840,8 @@ TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
request.url = GURL("http://www.example.org/");
request.load_flags = 0;
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
+ session_deps_.proxy_service =
+ ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
TestNetLog net_log;
session_deps_.net_log = &net_log;
@@ -7773,8 +7912,8 @@ TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
request.url = GURL("https://www.example.org/");
request.load_flags = 0;
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
+ session_deps_.proxy_service =
+ ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
TestNetLog net_log;
session_deps_.net_log = &net_log;
@@ -7864,8 +8003,10 @@ scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
session->http_server_properties();
AlternativeService alternative_service(
AlternateProtocolFromNextProto(next_proto), "", 443);
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties->SetAlternativeService(
- HostPortPair("host.with.alternate", 80), alternative_service, 1.0);
+ HostPortPair("host.with.alternate", 80), alternative_service, 1.0,
+ expiration);
return session;
}
@@ -7925,11 +8066,11 @@ TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
},
};
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
for (size_t i = 0; i < arraysize(tests); ++i) {
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixed(tests[i].proxy_server));
+ session_deps_.proxy_service =
+ ProxyService::CreateFixed(tests[i].proxy_server);
scoped_refptr<HttpNetworkSession> session(
SetupSessionForGroupNameTests(GetParam(), &session_deps_));
@@ -7953,7 +8094,6 @@ TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
EXPECT_EQ(tests[i].expected_group_name,
transport_conn_pool->last_group_name_received());
}
-
}
TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
@@ -7988,11 +8128,11 @@ TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
},
};
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
for (size_t i = 0; i < arraysize(tests); ++i) {
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixed(tests[i].proxy_server));
+ session_deps_.proxy_service =
+ ProxyService::CreateFixed(tests[i].proxy_server);
scoped_refptr<HttpNetworkSession> session(
SetupSessionForGroupNameTests(GetParam(), &session_deps_));
@@ -8058,11 +8198,11 @@ TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
},
};
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
for (size_t i = 0; i < arraysize(tests); ++i) {
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixed(tests[i].proxy_server));
+ session_deps_.proxy_service =
+ ProxyService::CreateFixed(tests[i].proxy_server);
scoped_refptr<HttpNetworkSession> session(
SetupSessionForGroupNameTests(GetParam(), &session_deps_));
@@ -8099,8 +8239,8 @@ TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
request.method = "GET";
request.url = GURL("http://www.example.org/");
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixed("myproxy:70;foobar:80"));
+ session_deps_.proxy_service =
+ ProxyService::CreateFixed("myproxy:70;foobar:80");
// This simulates failure resolving all hostnames; that means we will fail
// connecting to both proxies (myproxy:70 and foobar:80).
@@ -8213,6 +8353,10 @@ TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
rv = callback.WaitForResult();
EXPECT_EQ(ERR_CONNECTION_RESET, rv);
+
+ IPEndPoint endpoint;
+ EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
+ EXPECT_LT(0u, endpoint.address().size());
}
// Check that a connection closed after the start of the headers finishes ok.
@@ -8252,6 +8396,10 @@ TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
rv = ReadTransaction(trans.get(), &response_data);
EXPECT_EQ(OK, rv);
EXPECT_EQ("", response_data);
+
+ IPEndPoint endpoint;
+ EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
+ EXPECT_LT(0u, endpoint.address().size());
}
// Make sure that a dropped connection while draining the body for auth
@@ -8337,7 +8485,7 @@ TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
// Test HTTPS connections going through a proxy that sends extra data.
TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
- session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
HttpRequestInfo request;
request.method = "GET";
@@ -8556,7 +8704,6 @@ TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
// Tests that changes to Auth realms are treated like auth rejections.
TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
-
HttpRequestInfo request;
request.method = "GET";
request.url = GURL("http://www.example.org/");
@@ -8711,18 +8858,207 @@ TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
EXPECT_TRUE(response->auth_challenge.get() == NULL);
}
+TEST_P(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
+ session_deps_.next_protos = SpdyNextProtos();
+ session_deps_.use_alternative_services = true;
+
+ std::string alternative_service_http_header =
+ GetAlternativeServiceHttpHeader();
+
+ MockRead data_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead(alternative_service_http_header.c_str()),
+ MockRead("\r\n"),
+ MockRead("hello world"),
+ MockRead(SYNCHRONOUS, OK),
+ };
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://www.example.org/");
+ request.load_flags = 0;
+
+ StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
+
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+ TestCompletionCallback callback;
+
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+
+ int rv = trans->Start(&request, callback.callback(), BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ HostPortPair http_host_port_pair("www.example.org", 80);
+ HttpServerProperties& http_server_properties =
+ *session->http_server_properties();
+ AlternativeServiceVector alternative_service_vector =
+ http_server_properties.GetAlternativeServices(http_host_port_pair);
+ EXPECT_TRUE(alternative_service_vector.empty());
+
+ EXPECT_EQ(OK, callback.WaitForResult());
+
+ const HttpResponseInfo* response = trans->GetResponseInfo();
+ ASSERT_TRUE(response != NULL);
+ ASSERT_TRUE(response->headers.get() != NULL);
+ EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_FALSE(response->was_fetched_via_spdy);
+ EXPECT_FALSE(response->was_npn_negotiated);
+
+ std::string response_data;
+ ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
+ EXPECT_EQ("hello world", response_data);
+
+ alternative_service_vector =
+ http_server_properties.GetAlternativeServices(http_host_port_pair);
+ ASSERT_EQ(1u, alternative_service_vector.size());
+ EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
+ alternative_service_vector[0].protocol);
+ EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
+ EXPECT_EQ(443, alternative_service_vector[0].port);
+}
+
+// Alternative Service headers must be ignored when |use_alternative_services|
+// is false.
+TEST_P(HttpNetworkTransactionTest, DoNotHonorAlternativeServiceHeader) {
+ session_deps_.next_protos = SpdyNextProtos();
+ session_deps_.use_alternative_services = false;
+
+ std::string alternative_service_http_header =
+ GetAlternativeServiceHttpHeader();
+
+ MockRead data_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead(alternative_service_http_header.c_str()),
+ MockRead("\r\n"),
+ MockRead("hello world"),
+ MockRead(SYNCHRONOUS, OK),
+ };
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://www.example.org/");
+ request.load_flags = 0;
+
+ StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
+
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+ TestCompletionCallback callback;
+
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+
+ int rv = trans->Start(&request, callback.callback(), BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ HostPortPair http_host_port_pair("www.example.org", 80);
+ HttpServerProperties& http_server_properties =
+ *session->http_server_properties();
+ AlternativeServiceVector alternative_service_vector =
+ http_server_properties.GetAlternativeServices(http_host_port_pair);
+ EXPECT_TRUE(alternative_service_vector.empty());
+
+ EXPECT_EQ(OK, callback.WaitForResult());
+
+ const HttpResponseInfo* response = trans->GetResponseInfo();
+ ASSERT_TRUE(response != nullptr);
+ ASSERT_TRUE(response->headers.get() != nullptr);
+ EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_FALSE(response->was_fetched_via_spdy);
+ EXPECT_FALSE(response->was_npn_negotiated);
+
+ std::string response_data;
+ ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
+ EXPECT_EQ("hello world", response_data);
+
+ alternative_service_vector =
+ http_server_properties.GetAlternativeServices(http_host_port_pair);
+ EXPECT_TRUE(alternative_service_vector.empty());
+}
+
+TEST_P(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeader) {
+ session_deps_.next_protos = SpdyNextProtos();
+ session_deps_.use_alternative_services = true;
+
+ MockRead data_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead("Alt-Svc: "),
+ MockRead(GetAlternateProtocolFromParam()),
+ MockRead("=\"www.example.com:443\";p=1.0,"),
+ MockRead("quic=\":1234\"\r\n\r\n"),
+ MockRead("hello world"),
+ MockRead(SYNCHRONOUS, OK),
+ };
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://www.example.org/");
+ request.load_flags = 0;
+
+ StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
+
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+ TestCompletionCallback callback;
+
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+
+ int rv = trans->Start(&request, callback.callback(), BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ HostPortPair http_host_port_pair("www.example.org", 80);
+ HttpServerProperties& http_server_properties =
+ *session->http_server_properties();
+ AlternativeServiceVector alternative_service_vector =
+ http_server_properties.GetAlternativeServices(http_host_port_pair);
+ EXPECT_TRUE(alternative_service_vector.empty());
+
+ EXPECT_EQ(OK, callback.WaitForResult());
+
+ const HttpResponseInfo* response = trans->GetResponseInfo();
+ ASSERT_TRUE(response != NULL);
+ ASSERT_TRUE(response->headers.get() != NULL);
+ EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_FALSE(response->was_fetched_via_spdy);
+ EXPECT_FALSE(response->was_npn_negotiated);
+
+ std::string response_data;
+ ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
+ EXPECT_EQ("hello world", response_data);
+
+ alternative_service_vector =
+ http_server_properties.GetAlternativeServices(http_host_port_pair);
+ ASSERT_EQ(2u, alternative_service_vector.size());
+ EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
+ alternative_service_vector[0].protocol);
+ EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
+ EXPECT_EQ(443, alternative_service_vector[0].port);
+ EXPECT_EQ(QUIC, alternative_service_vector[1].protocol);
+ EXPECT_EQ("www.example.org", alternative_service_vector[1].host);
+ EXPECT_EQ(1234, alternative_service_vector[1].port);
+}
+
+// Alternate Protocol headers must be honored even if |use_alternative_services|
+// is false.
TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
session_deps_.next_protos = SpdyNextProtos();
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = false;
std::string alternate_protocol_http_header =
GetAlternateProtocolHttpHeader();
MockRead data_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead(alternate_protocol_http_header.c_str()),
- MockRead("hello world"),
- MockRead(SYNCHRONOUS, OK),
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead(alternate_protocol_http_header.c_str()),
+ MockRead("\r\n"),
+ MockRead("hello world"),
+ MockRead(SYNCHRONOUS, OK),
};
HttpRequestInfo request;
@@ -8773,7 +9109,7 @@ TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
TEST_P(HttpNetworkTransactionTest, EmptyAlternateProtocolHeader) {
session_deps_.next_protos = SpdyNextProtos();
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
MockRead data_reads[] = {
MockRead("HTTP/1.1 200 OK\r\n"),
@@ -8799,8 +9135,9 @@ TEST_P(HttpNetworkTransactionTest, EmptyAlternateProtocolHeader) {
HttpServerProperties& http_server_properties =
*session->http_server_properties();
AlternativeService alternative_service(QUIC, "", 80);
- http_server_properties.SetAlternativeService(http_host_port_pair,
- alternative_service, 1.0);
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
+ http_server_properties.SetAlternativeService(
+ http_host_port_pair, alternative_service, 1.0, expiration);
AlternativeServiceVector alternative_service_vector =
http_server_properties.GetAlternativeServices(http_host_port_pair);
@@ -8831,9 +9168,117 @@ TEST_P(HttpNetworkTransactionTest, EmptyAlternateProtocolHeader) {
EXPECT_TRUE(alternative_service_vector.empty());
}
+TEST_P(HttpNetworkTransactionTest, AltSvcOverwritesAlternateProtocol) {
+ session_deps_.next_protos = SpdyNextProtos();
+ session_deps_.use_alternative_services = true;
+
+ std::string alternative_service_http_header =
+ GetAlternativeServiceHttpHeader();
+ std::string alternate_protocol_http_header = GetAlternateProtocolHttpHeader();
+
+ MockRead data_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead(alternative_service_http_header.c_str()),
+ MockRead(alternate_protocol_http_header.c_str()),
+ MockRead("\r\n"),
+ MockRead("hello world"),
+ MockRead(SYNCHRONOUS, OK),
+ };
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://www.example.org/");
+ request.load_flags = 0;
+
+ StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
+
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+ TestCompletionCallback callback;
+
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+
+ int rv = trans->Start(&request, callback.callback(), BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ HostPortPair http_host_port_pair("www.example.org", 80);
+ HttpServerProperties& http_server_properties =
+ *session->http_server_properties();
+ AlternativeServiceVector alternative_service_vector =
+ http_server_properties.GetAlternativeServices(http_host_port_pair);
+ EXPECT_TRUE(alternative_service_vector.empty());
+
+ EXPECT_EQ(OK, callback.WaitForResult());
+
+ const HttpResponseInfo* response = trans->GetResponseInfo();
+ ASSERT_TRUE(response != NULL);
+ ASSERT_TRUE(response->headers.get() != NULL);
+ EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_FALSE(response->was_fetched_via_spdy);
+ EXPECT_FALSE(response->was_npn_negotiated);
+
+ std::string response_data;
+ ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
+ EXPECT_EQ("hello world", response_data);
+
+ alternative_service_vector =
+ http_server_properties.GetAlternativeServices(http_host_port_pair);
+ ASSERT_EQ(1u, alternative_service_vector.size());
+ EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
+ alternative_service_vector[0].protocol);
+ EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
+ EXPECT_EQ(443, alternative_service_vector[0].port);
+}
+
+// When |use_alternative_services| is false, do not observe alternative service
+// entries that point to a different host.
+TEST_P(HttpNetworkTransactionTest, DisableAlternativeServiceToDifferentHost) {
+ session_deps_.use_alternative_services = false;
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://www.example.org/");
+ request.load_flags = 0;
+
+ MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
+ StaticSocketDataProvider first_data;
+ first_data.set_connect_data(mock_connect);
+ session_deps_.socket_factory->AddSocketDataProvider(&first_data);
+
+ MockRead data_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
+ MockRead(ASYNC, OK),
+ };
+ StaticSocketDataProvider second_data(data_reads, arraysize(data_reads),
+ nullptr, 0);
+ session_deps_.socket_factory->AddSocketDataProvider(&second_data);
+
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+
+ base::WeakPtr<HttpServerProperties> http_server_properties =
+ session->http_server_properties();
+ AlternativeService alternative_service(
+ AlternateProtocolFromNextProto(GetParam()), "different.example.org", 80);
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
+ http_server_properties->SetAlternativeService(
+ HostPortPair::FromURL(request.url), alternative_service, 1.0, expiration);
+
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+ TestCompletionCallback callback;
+
+ int rv = trans->Start(&request, callback.callback(), BoundNetLog());
+ // The connetion to origin was refused, and the alternative service should not
+ // be used (even though mock data are there), therefore the request should
+ // fail.
+ EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
+}
+
TEST_P(HttpNetworkTransactionTest,
MarkBrokenAlternateProtocolAndFallback) {
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
HttpRequestInfo request;
request.method = "GET";
@@ -8864,8 +9309,9 @@ TEST_P(HttpNetworkTransactionTest,
const AlternativeService alternative_service(
AlternateProtocolFromNextProto(GetParam()), "www.example.org",
666); // Port is ignored by MockConnect anyway.
- http_server_properties->SetAlternativeService(host_port_pair,
- alternative_service, 1.0);
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
+ http_server_properties->SetAlternativeService(
+ host_port_pair, alternative_service, 1.0, expiration);
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -8892,13 +9338,13 @@ TEST_P(HttpNetworkTransactionTest,
alternative_service_vector[0]));
}
+// Ensure that we are not allowed to redirect traffic via an alternate protocol
+// to an unrestricted (port >= 1024) when the original traffic was on a
+// restricted port (port < 1024). Ensure that we can redirect in all other
+// cases.
TEST_P(HttpNetworkTransactionTest,
AlternateProtocolPortRestrictedBlocked) {
- // Ensure that we're not allowed to redirect traffic via an alternate
- // protocol to an unrestricted (port >= 1024) when the original traffic was
- // on a restricted port (port < 1024). Ensure that we can redirect in all
- // other cases.
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
HttpRequestInfo restricted_port_request;
restricted_port_request.method = "GET";
@@ -8927,9 +9373,10 @@ TEST_P(HttpNetworkTransactionTest,
AlternativeService alternative_service(
AlternateProtocolFromNextProto(GetParam()), "www.example.org",
kUnrestrictedAlternatePort);
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties->SetAlternativeService(
HostPortPair::FromURL(restricted_port_request.url), alternative_service,
- 1.0);
+ 1.0, expiration);
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -8943,14 +9390,12 @@ TEST_P(HttpNetworkTransactionTest,
EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
}
+// Ensure that we are allowed to redirect traffic via an alternate protocol to
+// an unrestricted (port >= 1024) when the original traffic was on a restricted
+// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
TEST_P(HttpNetworkTransactionTest,
AlternateProtocolPortRestrictedPermitted) {
- // Ensure that we're allowed to redirect traffic via an alternate
- // protocol to an unrestricted (port >= 1024) when the original traffic was
- // on a restricted port (port < 1024) if we set
- // enable_user_alternate_protocol_ports.
-
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
session_deps_.enable_user_alternate_protocol_ports = true;
HttpRequestInfo restricted_port_request;
@@ -8980,9 +9425,10 @@ TEST_P(HttpNetworkTransactionTest,
AlternativeService alternative_service(
AlternateProtocolFromNextProto(GetParam()), "www.example.org",
kUnrestrictedAlternatePort);
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties->SetAlternativeService(
HostPortPair::FromURL(restricted_port_request.url), alternative_service,
- 1.0);
+ 1.0, expiration);
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -8995,13 +9441,13 @@ TEST_P(HttpNetworkTransactionTest,
EXPECT_EQ(OK, callback.WaitForResult());
}
+// Ensure that we are not allowed to redirect traffic via an alternate protocol
+// to an unrestricted (port >= 1024) when the original traffic was on a
+// restricted port (port < 1024). Ensure that we can redirect in all other
+// cases.
TEST_P(HttpNetworkTransactionTest,
AlternateProtocolPortRestrictedAllowed) {
- // Ensure that we're not allowed to redirect traffic via an alternate
- // protocol to an unrestricted (port >= 1024) when the original traffic was
- // on a restricted port (port < 1024). Ensure that we can redirect in all
- // other cases.
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
HttpRequestInfo restricted_port_request;
restricted_port_request.method = "GET";
@@ -9030,9 +9476,10 @@ TEST_P(HttpNetworkTransactionTest,
AlternativeService alternative_service(
AlternateProtocolFromNextProto(GetParam()), "www.example.org",
kRestrictedAlternatePort);
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties->SetAlternativeService(
HostPortPair::FromURL(restricted_port_request.url), alternative_service,
- 1.0);
+ 1.0, expiration);
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -9046,13 +9493,13 @@ TEST_P(HttpNetworkTransactionTest,
EXPECT_EQ(OK, callback.WaitForResult());
}
+// Ensure that we are not allowed to redirect traffic via an alternate protocol
+// to an unrestricted (port >= 1024) when the original traffic was on a
+// restricted port (port < 1024). Ensure that we can redirect in all other
+// cases.
TEST_P(HttpNetworkTransactionTest,
AlternateProtocolPortUnrestrictedAllowed1) {
- // Ensure that we're not allowed to redirect traffic via an alternate
- // protocol to an unrestricted (port >= 1024) when the original traffic was
- // on a restricted port (port < 1024). Ensure that we can redirect in all
- // other cases.
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
HttpRequestInfo unrestricted_port_request;
unrestricted_port_request.method = "GET";
@@ -9081,9 +9528,10 @@ TEST_P(HttpNetworkTransactionTest,
AlternativeService alternative_service(
AlternateProtocolFromNextProto(GetParam()), "www.example.org",
kRestrictedAlternatePort);
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties->SetAlternativeService(
HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
- 1.0);
+ 1.0, expiration);
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -9096,13 +9544,13 @@ TEST_P(HttpNetworkTransactionTest,
EXPECT_EQ(OK, callback.WaitForResult());
}
+// Ensure that we are not allowed to redirect traffic via an alternate protocol
+// to an unrestricted (port >= 1024) when the original traffic was on a
+// restricted port (port < 1024). Ensure that we can redirect in all other
+// cases.
TEST_P(HttpNetworkTransactionTest,
AlternateProtocolPortUnrestrictedAllowed2) {
- // Ensure that we're not allowed to redirect traffic via an alternate
- // protocol to an unrestricted (port >= 1024) when the original traffic was
- // on a restricted port (port < 1024). Ensure that we can redirect in all
- // other cases.
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
HttpRequestInfo unrestricted_port_request;
unrestricted_port_request.method = "GET";
@@ -9127,13 +9575,14 @@ TEST_P(HttpNetworkTransactionTest,
base::WeakPtr<HttpServerProperties> http_server_properties =
session->http_server_properties();
- const int kUnrestrictedAlternatePort = 1024;
+ const int kUnrestrictedAlternatePort = 1025;
AlternativeService alternative_service(
AlternateProtocolFromNextProto(GetParam()), "www.example.org",
kUnrestrictedAlternatePort);
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties->SetAlternativeService(
HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
- 1.0);
+ 1.0, expiration);
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -9146,11 +9595,11 @@ TEST_P(HttpNetworkTransactionTest,
EXPECT_EQ(OK, callback.WaitForResult());
}
+// Ensure that we are not allowed to redirect traffic via an alternate protocol
+// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
+// once the alternate protocol request fails.
TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
- // Ensure that we're not allowed to redirect traffic via an alternate
- // protocol to an unsafe port, and that we resume the second
- // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
HttpRequestInfo request;
request.method = "GET";
@@ -9176,8 +9625,9 @@ TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
AlternativeService alternative_service(
AlternateProtocolFromNextProto(GetParam()), "www.example.org",
kUnsafePort);
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties->SetAlternativeService(
- HostPortPair::FromURL(request.url), alternative_service, 1.0);
+ HostPortPair::FromURL(request.url), alternative_service, 1.0, expiration);
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -9188,9 +9638,6 @@ TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
// The HTTP request should succeed.
EXPECT_EQ(OK, callback.WaitForResult());
- // Disable alternate protocol before the asserts.
- // HttpStreamFactory::set_use_alternate_protocols(false);
-
const HttpResponseInfo* response = trans->GetResponseInfo();
ASSERT_TRUE(response != NULL);
ASSERT_TRUE(response->headers.get() != NULL);
@@ -9202,7 +9649,7 @@ TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
}
TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
session_deps_.next_protos = SpdyNextProtos();
HttpRequestInfo request;
@@ -9214,12 +9661,12 @@ TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
GetAlternateProtocolHttpHeader();
MockRead data_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead(alternate_protocol_http_header.c_str()),
- MockRead("hello world"),
- MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
- MockRead(ASYNC, OK)
- };
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead(alternate_protocol_http_header.c_str()),
+ MockRead("\r\n"),
+ MockRead("hello world"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK)};
StaticSocketDataProvider first_transaction(
data_reads, arraysize(data_reads), NULL, 0);
@@ -9290,7 +9737,7 @@ TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
}
TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
session_deps_.next_protos = SpdyNextProtos();
HttpRequestInfo request;
@@ -9302,11 +9749,12 @@ TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
GetAlternateProtocolHttpHeader();
MockRead data_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead(alternate_protocol_http_header.c_str()),
- MockRead("hello world"),
- MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
- MockRead(ASYNC, OK),
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead(alternate_protocol_http_header.c_str()),
+ MockRead("\r\n"),
+ MockRead("hello world"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK),
};
StaticSocketDataProvider first_transaction(
@@ -9406,7 +9854,7 @@ TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
}
TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
session_deps_.next_protos = SpdyNextProtos();
HttpRequestInfo request;
@@ -9418,11 +9866,12 @@ TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
GetAlternateProtocolHttpHeader();
MockRead data_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead(alternate_protocol_http_header.c_str()),
- MockRead("hello world"),
- MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
- MockRead(ASYNC, OK),
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead(alternate_protocol_http_header.c_str()),
+ MockRead("\r\n"),
+ MockRead("hello world"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK),
};
StaticSocketDataProvider first_transaction(
@@ -9532,7 +9981,7 @@ class CapturingProxyResolverFactory : public ProxyResolverFactory {
TEST_P(HttpNetworkTransactionTest,
UseAlternateProtocolForTunneledNpnSpdy) {
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
session_deps_.next_protos = SpdyNextProtos();
ProxyConfig proxy_config;
@@ -9541,7 +9990,7 @@ TEST_P(HttpNetworkTransactionTest,
CapturingProxyResolver capturing_proxy_resolver;
session_deps_.proxy_service.reset(new ProxyService(
- new ProxyConfigServiceFixed(proxy_config),
+ make_scoped_ptr(new ProxyConfigServiceFixed(proxy_config)),
make_scoped_ptr(
new CapturingProxyResolverFactory(&capturing_proxy_resolver)),
NULL));
@@ -9557,11 +10006,12 @@ TEST_P(HttpNetworkTransactionTest,
GetAlternateProtocolHttpHeader();
MockRead data_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead(alternate_protocol_http_header.c_str()),
- MockRead("hello world"),
- MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
- MockRead(ASYNC, OK),
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead(alternate_protocol_http_header.c_str()),
+ MockRead("\r\n"),
+ MockRead("hello world"),
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
+ MockRead(ASYNC, OK),
};
StaticSocketDataProvider first_transaction(
@@ -9657,7 +10107,7 @@ TEST_P(HttpNetworkTransactionTest,
TEST_P(HttpNetworkTransactionTest,
UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
session_deps_.next_protos = SpdyNextProtos();
HttpRequestInfo request;
@@ -9669,10 +10119,11 @@ TEST_P(HttpNetworkTransactionTest,
GetAlternateProtocolHttpHeader();
MockRead data_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead(alternate_protocol_http_header.c_str()),
- MockRead("hello world"),
- MockRead(ASYNC, OK),
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead(alternate_protocol_http_header.c_str()),
+ MockRead("\r\n"),
+ MockRead("hello world"),
+ MockRead(ASYNC, OK),
};
StaticSocketDataProvider first_transaction(
@@ -10082,10 +10533,10 @@ TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
}
if (test_config.proxy_url) {
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixed(test_config.proxy_url));
+ session_deps_.proxy_service =
+ ProxyService::CreateFixed(test_config.proxy_url);
} else {
- session_deps_.proxy_service.reset(ProxyService::CreateDirect());
+ session_deps_.proxy_service = ProxyService::CreateDirect();
}
HttpRequestInfo request;
@@ -10172,7 +10623,7 @@ TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
HttpAuthHandlerMock::Factory* auth_factory(
new HttpAuthHandlerMock::Factory());
session_deps_.http_auth_handler_factory.reset(auth_factory);
- session_deps_.proxy_service.reset(ProxyService::CreateDirect());
+ session_deps_.proxy_service = ProxyService::CreateDirect();
session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
session_deps_.host_resolver->set_synchronous_mode(true);
@@ -10354,7 +10805,7 @@ TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
// This tests the case that a request is issued via http instead of spdy after
// npn is negotiated.
TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
NextProtoVector next_protos;
next_protos.push_back(kProtoHTTP11);
session_deps_.next_protos = next_protos;
@@ -10375,10 +10826,11 @@ TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
GetAlternateProtocolHttpHeader();
MockRead data_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead(alternate_protocol_http_header.c_str()),
- MockRead("hello world"),
- MockRead(SYNCHRONOUS, OK),
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead(alternate_protocol_http_header.c_str()),
+ MockRead("\r\n"),
+ MockRead("hello world"),
+ MockRead(SYNCHRONOUS, OK),
};
SSLSocketDataProvider ssl(ASYNC, OK);
@@ -10414,11 +10866,11 @@ TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
EXPECT_TRUE(response->was_npn_negotiated);
}
+// Simulate the SSL handshake completing with an NPN negotiation followed by an
+// immediate server closing of the socket.
+// Regression test for https://crbug.com/46369.
TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
- // Simulate the SSL handshake completing with an NPN negotiation
- // followed by an immediate server closing of the socket.
- // Fix crash: http://crbug.com/46369
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
session_deps_.next_protos = SpdyNextProtos();
HttpRequestInfo request;
@@ -10476,14 +10928,14 @@ class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
GURL* url_;
};
+// This test ensures that the URL passed into the proxy is upgraded to https
+// when doing an Alternate Protocol upgrade.
TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
- // This test ensures that the URL passed into the proxy is upgraded
- // to https when doing an Alternate Protocol upgrade.
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
session_deps_.next_protos = SpdyNextProtos();
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
+ session_deps_.proxy_service =
+ ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
TestNetLog net_log;
session_deps_.net_log = &net_log;
GURL request_url;
@@ -10731,8 +11183,8 @@ TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
// Test a basic GET request through a proxy.
TEST_P(HttpNetworkTransactionTest, ProxyGet) {
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
+ session_deps_.proxy_service =
+ ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -10795,8 +11247,8 @@ TEST_P(HttpNetworkTransactionTest, ProxyGet) {
// Test a basic HTTPS GET request through a proxy.
TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
+ session_deps_.proxy_service =
+ ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -10873,7 +11325,7 @@ TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
// Test a basic HTTPS GET request through a proxy, but the server hangs up
// while establishing the tunnel.
TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
- session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -11244,8 +11696,7 @@ TEST_P(HttpNetworkTransactionTest,
// The test is repeated twice, first for connecting to an HTTPS endpoint,
// then for connecting to an HTTP endpoint.
TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixed("https://proxy:70"));
+ session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
BoundTestNetLog log;
session_deps_.net_log = log.bound().net_log();
@@ -11336,7 +11787,7 @@ TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
}
TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
session_deps_.next_protos = SpdyNextProtos();
// Set up a special HttpNetworkSession with a MockCachingHostResolver.
@@ -11435,7 +11886,7 @@ TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
}
TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
session_deps_.next_protos = SpdyNextProtos();
// Set up a special HttpNetworkSession with a MockCachingHostResolver.
@@ -11562,7 +12013,7 @@ class OneTimeCachingHostResolver : public HostResolver {
TEST_P(HttpNetworkTransactionTest,
UseIPConnectionPoolingWithHostCacheExpiration) {
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
session_deps_.next_protos = SpdyNextProtos();
// Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
@@ -11821,14 +12272,15 @@ class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
data_refused.set_connect_data(mock_connect);
session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
base::WeakPtr<HttpServerProperties> http_server_properties =
session->http_server_properties();
AlternativeService alternative_service(
AlternateProtocolFromNextProto(GetParam()), alternative);
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties->SetAlternativeService(origin, alternative_service,
- 1.0);
+ 1.0, expiration);
// First request to alternative.
if (pooling) {
@@ -11877,7 +12329,6 @@ class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
INSTANTIATE_TEST_CASE_P(NextProto,
AltSvcCertificateVerificationTest,
testing::Values(kProtoSPDY31,
- kProtoHTTP2_14,
kProtoHTTP2));
// The alternative service host must exhibit a certificate that is valid for the
@@ -11925,14 +12376,15 @@ TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
// Set up alternative service for origin.
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
base::WeakPtr<HttpServerProperties> http_server_properties =
session->http_server_properties();
AlternativeService alternative_service(
AlternateProtocolFromNextProto(GetParam()), alternative);
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties->SetAlternativeService(origin, alternative_service,
- 1.0);
+ 1.0, expiration);
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -11997,14 +12449,15 @@ TEST_P(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
session_deps_.socket_factory->AddSocketDataProvider(&http_data);
// Set up alternative service for origin.
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
base::WeakPtr<HttpServerProperties> http_server_properties =
session->http_server_properties();
AlternativeService alternative_service(
AlternateProtocolFromNextProto(GetParam()), alternative);
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties->SetAlternativeService(origin, alternative_service,
- 1.0);
+ 1.0, expiration);
HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
HttpRequestInfo request1;
@@ -12105,14 +12558,15 @@ TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
// Set up alternative service for origin.
- session_deps_.use_alternate_protocols = true;
+ session_deps_.use_alternative_services = true;
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
base::WeakPtr<HttpServerProperties> http_server_properties =
session->http_server_properties();
AlternativeService alternative_service(
AlternateProtocolFromNextProto(GetParam()), alternative);
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
http_server_properties->SetAlternativeService(origin, alternative_service,
- 1.0);
+ 1.0, expiration);
// First transaction to alternative to open an HTTP/1.1 socket.
scoped_ptr<HttpTransaction> trans1(
@@ -12189,11 +12643,11 @@ TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
// SPDY GET for HTTP URL (through the proxy, but not the tunnel).
SpdyHeaderBlock req2_block;
+ spdy_util_.MaybeAddVersionHeader(&req2_block);
req2_block[spdy_util_.GetMethodKey()] = "GET";
- req2_block[spdy_util_.GetPathKey()] = "/";
req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
req2_block[spdy_util_.GetSchemeKey()] = "http";
- spdy_util_.MaybeAddVersionHeader(&req2_block);
+ req2_block[spdy_util_.GetPathKey()] = "/";
scoped_ptr<SpdyFrame> req2(
spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
@@ -12227,8 +12681,8 @@ TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
MockConnect connect_data1(ASYNC, OK);
data1.set_connect_data(connect_data1);
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
+ session_deps_.proxy_service =
+ ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
TestNetLog log;
session_deps_.net_log = &log;
SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
@@ -12308,9 +12762,9 @@ TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
MockRead reads1[] = {
- CreateMockRead(*resp1, 1),
- CreateMockRead(*body1, 2),
- MockRead(ASYNC, OK, 3) // EOF
+ CreateMockRead(*resp1, 1),
+ CreateMockRead(*body1, 2),
+ MockRead(ASYNC, OK, 3) // EOF
};
scoped_ptr<DeterministicSocketData> data1(
@@ -12333,9 +12787,9 @@ TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
MockRead reads2[] = {
- CreateMockRead(*resp2, 1),
- CreateMockRead(*body2, 2),
- MockRead(ASYNC, OK, 3) // EOF
+ CreateMockRead(*resp2, 1),
+ CreateMockRead(*body2, 2),
+ MockRead(ASYNC, OK, 3) // EOF
};
scoped_ptr<DeterministicSocketData> data2(
@@ -12349,7 +12803,8 @@ TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
ProxyConfig proxy_config;
proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
session_deps_.proxy_service.reset(new ProxyService(
- new ProxyConfigServiceFixed(proxy_config), nullptr, NULL));
+ make_scoped_ptr(new ProxyConfigServiceFixed(proxy_config)), nullptr,
+ NULL));
SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
ssl1.SetNextProto(GetParam());
@@ -12651,7 +13106,7 @@ TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
- MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
+ MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
StaticSocketDataProvider data;
data.set_connect_data(mock_connect);
session_deps_.socket_factory->AddSocketDataProvider(&data);
@@ -12662,7 +13117,7 @@ TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
EXPECT_EQ(ERR_IO_PENDING, rv);
rv = callback.WaitForResult();
- EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
+ EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
// We don't care whether this succeeds or fails, but it shouldn't crash.
HttpRequestHeaders request_headers;
@@ -12671,7 +13126,11 @@ TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
ConnectionAttempts attempts;
trans->GetConnectionAttempts(&attempts);
ASSERT_EQ(1u, attempts.size());
- EXPECT_EQ(ERR_CONNECTION_REFUSED, attempts[0].result);
+ EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
+
+ IPEndPoint endpoint;
+ EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
+ EXPECT_TRUE(endpoint.address().empty());
}
TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
@@ -12684,7 +13143,7 @@ TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
- MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
+ MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
StaticSocketDataProvider data;
data.set_connect_data(mock_connect);
session_deps_.socket_factory->AddSocketDataProvider(&data);
@@ -12695,7 +13154,7 @@ TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
EXPECT_EQ(ERR_IO_PENDING, rv);
rv = callback.WaitForResult();
- EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
+ EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
// We don't care whether this succeeds or fails, but it shouldn't crash.
HttpRequestHeaders request_headers;
@@ -12704,7 +13163,11 @@ TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
ConnectionAttempts attempts;
trans->GetConnectionAttempts(&attempts);
ASSERT_EQ(1u, attempts.size());
- EXPECT_EQ(ERR_CONNECTION_REFUSED, attempts[0].result);
+ EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
+
+ IPEndPoint endpoint;
+ EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
+ EXPECT_TRUE(endpoint.address().empty());
}
TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
@@ -12937,8 +13400,6 @@ class FakeStream : public HttpStream,
return false;
}
- bool CanFindEndOfResponse() const override { return false; }
-
bool IsConnectionReused() const override {
ADD_FAILURE();
return false;
@@ -12946,12 +13407,14 @@ class FakeStream : public HttpStream,
void SetConnectionReused() override { ADD_FAILURE(); }
- bool IsConnectionReusable() const override {
+ bool CanReuseConnection() const override { return false; }
+
+ int64_t GetTotalReceivedBytes() const override {
ADD_FAILURE();
- return false;
+ return 0;
}
- int64 GetTotalReceivedBytes() const override {
+ int64_t GetTotalSentBytes() const override {
ADD_FAILURE();
return 0;
}
@@ -12967,10 +13430,7 @@ class FakeStream : public HttpStream,
ADD_FAILURE();
}
- bool IsSpdyHttpStream() const override {
- ADD_FAILURE();
- return false;
- }
+ bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
@@ -13094,7 +13554,6 @@ class FakeStreamFactory : public HttpStreamFactory {
void PreconnectStreams(int num_streams,
const HttpRequestInfo& info,
- RequestPriority priority,
const SSLConfig& server_ssl_config,
const SSLConfig& proxy_ssl_config) override {
ADD_FAILURE();
@@ -13160,22 +13619,20 @@ class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
return false;
}
- bool CanFindEndOfResponse() const override {
- return parser()->CanFindEndOfResponse();
- }
-
bool IsConnectionReused() const override {
NOTREACHED();
return false;
}
void SetConnectionReused() override { NOTREACHED(); }
- bool IsConnectionReusable() const override {
+ bool CanReuseConnection() const override { return false; }
+
+ int64_t GetTotalReceivedBytes() const override {
NOTREACHED();
- return false;
+ return 0;
}
- int64 GetTotalReceivedBytes() const override {
+ int64_t GetTotalSentBytes() const override {
NOTREACHED();
return 0;
}
@@ -13191,10 +13648,7 @@ class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
NOTREACHED();
}
- bool IsSpdyHttpStream() const override {
- NOTREACHED();
- return false;
- }
+ bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
@@ -13504,8 +13958,8 @@ TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
HttpStreamFactory* http_stream_factory = session->http_stream_factory();
SSLConfig ssl_config;
session->ssl_config_service()->GetSSLConfig(&ssl_config);
- http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
- ssl_config, ssl_config);
+ http_stream_factory->PreconnectStreams(1, ssl_request, ssl_config,
+ ssl_config);
EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
// Start the HTTP request. Pool should stall.
@@ -14007,8 +14461,8 @@ TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
AddWebSocketHeaders(&request.extra_headers);
// Configure against proxy server "myproxy:70".
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
+ session_deps_.proxy_service =
+ ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -14113,8 +14567,8 @@ TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
AddWebSocketHeaders(&request.extra_headers);
// Configure against proxy server "myproxy:70".
- session_deps_.proxy_service.reset(
- ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
+ session_deps_.proxy_service =
+ ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
@@ -14182,4 +14636,145 @@ TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
session->CloseAllConnections();
}
+TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
+ ScopedVector<UploadElementReader> element_readers;
+ element_readers.push_back(new UploadBytesElementReader("foo", 3));
+ ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+
+ HttpRequestInfo request;
+ request.method = "POST";
+ request.url = GURL("http://www.foo.com/");
+ request.upload_data_stream = &upload_data_stream;
+
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+ MockWrite data_writes[] = {
+ MockWrite("POST / HTTP/1.1\r\n"
+ "Host: www.foo.com\r\n"
+ "Connection: keep-alive\r\n"
+ "Content-Length: 3\r\n\r\n"),
+ MockWrite("foo"),
+ };
+
+ MockRead data_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
+ MockRead(SYNCHRONOUS, OK),
+ };
+ StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
+ arraysize(data_writes));
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+ TestCompletionCallback callback;
+
+ EXPECT_EQ(ERR_IO_PENDING,
+ trans->Start(&request, callback.callback(), BoundNetLog()));
+ EXPECT_EQ(OK, callback.WaitForResult());
+
+ std::string response_data;
+ EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
+
+ EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
+ trans->GetTotalSentBytes());
+ EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
+ trans->GetTotalReceivedBytes());
+}
+
+TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
+ ScopedVector<UploadElementReader> element_readers;
+ element_readers.push_back(new UploadBytesElementReader("foo", 3));
+ ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+
+ HttpRequestInfo request;
+ request.method = "POST";
+ request.url = GURL("http://www.foo.com/");
+ request.upload_data_stream = &upload_data_stream;
+
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+ MockWrite data_writes[] = {
+ MockWrite("POST / HTTP/1.1\r\n"
+ "Host: www.foo.com\r\n"
+ "Connection: keep-alive\r\n"
+ "Content-Length: 3\r\n\r\n"),
+ MockWrite("foo"),
+ };
+
+ MockRead data_reads[] = {
+ MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
+ MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
+ MockRead(SYNCHRONOUS, OK),
+ };
+ StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
+ arraysize(data_writes));
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+ TestCompletionCallback callback;
+
+ EXPECT_EQ(ERR_IO_PENDING,
+ trans->Start(&request, callback.callback(), BoundNetLog()));
+ EXPECT_EQ(OK, callback.WaitForResult());
+
+ std::string response_data;
+ EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
+
+ EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
+ trans->GetTotalSentBytes());
+ EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
+ trans->GetTotalReceivedBytes());
+}
+
+TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
+ ScopedVector<UploadElementReader> element_readers;
+ element_readers.push_back(new UploadBytesElementReader("foo", 3));
+ ChunkedUploadDataStream upload_data_stream(0);
+
+ HttpRequestInfo request;
+ request.method = "POST";
+ request.url = GURL("http://www.foo.com/");
+ request.upload_data_stream = &upload_data_stream;
+
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
+ // Send headers successfully, but get an error while sending the body.
+ MockWrite data_writes[] = {
+ MockWrite("POST / HTTP/1.1\r\n"
+ "Host: www.foo.com\r\n"
+ "Connection: keep-alive\r\n"
+ "Transfer-Encoding: chunked\r\n\r\n"),
+ MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
+ };
+
+ MockRead data_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
+ MockRead(SYNCHRONOUS, OK),
+ };
+ StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
+ arraysize(data_writes));
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+ TestCompletionCallback callback;
+
+ EXPECT_EQ(ERR_IO_PENDING,
+ trans->Start(&request, callback.callback(), BoundNetLog()));
+
+ base::RunLoop().RunUntilIdle();
+ upload_data_stream.AppendData("f", 1, false);
+
+ base::RunLoop().RunUntilIdle();
+ upload_data_stream.AppendData("oo", 2, true);
+
+ EXPECT_EQ(OK, callback.WaitForResult());
+
+ std::string response_data;
+ EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
+
+ EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
+ trans->GetTotalSentBytes());
+ EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
+ trans->GetTotalReceivedBytes());
+}
+
} // namespace net
diff --git a/chromium/net/http/http_proxy_client_socket_pool_unittest.cc b/chromium/net/http/http_proxy_client_socket_pool_unittest.cc
index 4fdebb2b22c..6b44dbbee49 100644
--- a/chromium/net/http/http_proxy_client_socket_pool_unittest.cc
+++ b/chromium/net/http/http_proxy_client_socket_pool_unittest.cc
@@ -326,10 +326,6 @@ INSTANTIATE_TEST_CASE_P(
::testing::Values(HttpProxyClientSocketPoolTestParams(HTTP, kProtoSPDY31),
HttpProxyClientSocketPoolTestParams(HTTPS, kProtoSPDY31),
HttpProxyClientSocketPoolTestParams(SPDY, kProtoSPDY31),
- HttpProxyClientSocketPoolTestParams(HTTP, kProtoHTTP2_14),
- HttpProxyClientSocketPoolTestParams(HTTPS,
- kProtoHTTP2_14),
- HttpProxyClientSocketPoolTestParams(SPDY, kProtoHTTP2_14),
HttpProxyClientSocketPoolTestParams(HTTP, kProtoHTTP2),
HttpProxyClientSocketPoolTestParams(HTTPS, kProtoHTTP2),
HttpProxyClientSocketPoolTestParams(SPDY, kProtoHTTP2)));
diff --git a/chromium/net/http/http_request_headers.cc b/chromium/net/http/http_request_headers.cc
index 004d0659512..c2eee59af95 100644
--- a/chromium/net/http/http_request_headers.cc
+++ b/chromium/net/http/http_request_headers.cc
@@ -241,8 +241,7 @@ HttpRequestHeaders::HeaderVector::iterator
HttpRequestHeaders::FindHeader(const base::StringPiece& key) {
for (HeaderVector::iterator it = headers_.begin();
it != headers_.end(); ++it) {
- if (key.length() == it->key.length() &&
- !base::strncasecmp(key.data(), it->key.data(), key.length()))
+ if (base::EqualsCaseInsensitiveASCII(key, it->key))
return it;
}
@@ -253,8 +252,7 @@ HttpRequestHeaders::HeaderVector::const_iterator
HttpRequestHeaders::FindHeader(const base::StringPiece& key) const {
for (HeaderVector::const_iterator it = headers_.begin();
it != headers_.end(); ++it) {
- if (key.length() == it->key.length() &&
- !base::strncasecmp(key.data(), it->key.data(), key.length()))
+ if (base::EqualsCaseInsensitiveASCII(key, it->key))
return it;
}
diff --git a/chromium/net/http/http_response_body_drainer.h b/chromium/net/http/http_response_body_drainer.h
index a4255d0dea9..33368225be6 100644
--- a/chromium/net/http/http_response_body_drainer.h
+++ b/chromium/net/http/http_response_body_drainer.h
@@ -56,7 +56,7 @@ class NET_EXPORT_PRIVATE HttpResponseBodyDrainer {
State next_state_;
int total_read_;
CompletionCallback user_callback_;
- base::OneShotTimer<HttpResponseBodyDrainer> timer_;
+ base::OneShotTimer timer_;
HttpNetworkSession* session_;
DISALLOW_COPY_AND_ASSIGN(HttpResponseBodyDrainer);
diff --git a/chromium/net/http/http_response_body_drainer_unittest.cc b/chromium/net/http/http_response_body_drainer_unittest.cc
index ca206b7f5c7..e44e6ee1e8a 100644
--- a/chromium/net/http/http_response_body_drainer_unittest.cc
+++ b/chromium/net/http/http_response_body_drainer_unittest.cc
@@ -4,6 +4,8 @@
#include "net/http/http_response_body_drainer.h"
+#include <stdint.h>
+
#include <cstring>
#include "base/bind.h"
@@ -96,13 +98,14 @@ class MockHttpStream : public HttpStream {
return ERR_UNEXPECTED;
}
- bool CanFindEndOfResponse() const override { return true; }
bool IsConnectionReused() const override { return false; }
void SetConnectionReused() override {}
- bool IsConnectionReusable() const override { return false; }
- int64 GetTotalReceivedBytes() const override { return 0; }
+ bool CanReuseConnection() const override { return false; }
+ int64_t GetTotalReceivedBytes() const override { return 0; }
+ int64_t GetTotalSentBytes() const override { return 0; }
void GetSSLInfo(SSLInfo* ssl_info) override {}
void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {}
+ bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
// Mocked API
int ReadResponseBody(IOBuffer* buf,
@@ -118,8 +121,6 @@ class MockHttpStream : public HttpStream {
bool IsResponseBodyComplete() const override { return is_complete_; }
- bool IsSpdyHttpStream() const override { return false; }
-
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
return false;
}
diff --git a/chromium/net/http/http_response_headers.cc b/chromium/net/http/http_response_headers.cc
index 7c0c5ad2ee1..c535e0ab64e 100644
--- a/chromium/net/http/http_response_headers.cc
+++ b/chromium/net/http/http_response_headers.cc
@@ -95,15 +95,13 @@ const char* const kNonUpdatedHeaderPrefixes[] = {
"x-webkit-"
};
-bool ShouldUpdateHeader(const std::string::const_iterator& name_begin,
- const std::string::const_iterator& name_end) {
+bool ShouldUpdateHeader(base::StringPiece name) {
for (size_t i = 0; i < arraysize(kNonUpdatedHeaders); ++i) {
- if (base::LowerCaseEqualsASCII(name_begin, name_end, kNonUpdatedHeaders[i]))
+ if (base::LowerCaseEqualsASCII(name, kNonUpdatedHeaders[i]))
return false;
}
for (size_t i = 0; i < arraysize(kNonUpdatedHeaderPrefixes); ++i) {
- if (base::StartsWith(base::StringPiece(name_begin, name_end),
- kNonUpdatedHeaderPrefixes[i],
+ if (base::StartsWith(name, kNonUpdatedHeaderPrefixes[i],
base::CompareCase::INSENSITIVE_ASCII))
return false;
}
@@ -208,9 +206,8 @@ void HttpResponseHeaders::Persist(base::Pickle* pickle,
while (++k < parsed_.size() && parsed_[k].is_continuation()) {}
--k;
- std::string header_name(parsed_[i].name_begin, parsed_[i].name_end);
- base::StringToLowerASCII(&header_name);
-
+ std::string header_name = base::ToLowerASCII(
+ base::StringPiece(parsed_[i].name_begin, parsed_[i].name_end));
if (filter_headers.find(header_name) == filter_headers.end()) {
// Make sure there is a null after the value.
blob.append(parsed_[i].name_begin, parsed_[k].value_end);
@@ -248,16 +245,14 @@ void HttpResponseHeaders::Update(const HttpResponseHeaders& new_headers) {
while (++k < new_parsed.size() && new_parsed[k].is_continuation()) {}
--k;
- const std::string::const_iterator& name_begin = new_parsed[i].name_begin;
- const std::string::const_iterator& name_end = new_parsed[i].name_end;
- if (ShouldUpdateHeader(name_begin, name_end)) {
- std::string name(name_begin, name_end);
- base::StringToLowerASCII(&name);
- updated_headers.insert(name);
+ base::StringPiece name(new_parsed[i].name_begin, new_parsed[i].name_end);
+ if (ShouldUpdateHeader(name)) {
+ std::string name_lower = base::ToLowerASCII(name);
+ updated_headers.insert(name_lower);
// Preserve this header line in the merged result, making sure there is
// a null after the value.
- new_raw_headers.append(name_begin, new_parsed[k].value_end);
+ new_raw_headers.append(new_parsed[i].name_begin, new_parsed[k].value_end);
new_raw_headers.push_back('\0');
}
@@ -279,8 +274,8 @@ void HttpResponseHeaders::MergeWithHeaders(const std::string& raw_headers,
while (++k < parsed_.size() && parsed_[k].is_continuation()) {}
--k;
- std::string name(parsed_[i].name_begin, parsed_[i].name_end);
- base::StringToLowerASCII(&name);
+ std::string name = base::ToLowerASCII(
+ base::StringPiece(parsed_[i].name_begin, parsed_[i].name_end));
if (headers_to_remove.find(name) == headers_to_remove.end()) {
// It's ok to preserve this header in the final result.
new_raw_headers.append(parsed_[i].name_begin, parsed_[k].value_end);
@@ -302,8 +297,7 @@ void HttpResponseHeaders::RemoveHeader(const std::string& name) {
std::string new_raw_headers(raw_headers_.c_str());
new_raw_headers.push_back('\0');
- std::string lowercase_name(name);
- base::StringToLowerASCII(&lowercase_name);
+ std::string lowercase_name = base::ToLowerASCII(name);
HeaderSet to_remove;
to_remove.insert(lowercase_name);
MergeWithHeaders(new_raw_headers, to_remove);
@@ -311,8 +305,7 @@ void HttpResponseHeaders::RemoveHeader(const std::string& name) {
void HttpResponseHeaders::RemoveHeaderLine(const std::string& name,
const std::string& value) {
- std::string name_lowercase(name);
- base::StringToLowerASCII(&name_lowercase);
+ std::string name_lowercase = base::ToLowerASCII(name);
std::string new_raw_headers(GetStatusLine());
new_raw_headers.push_back('\0');
@@ -323,9 +316,7 @@ void HttpResponseHeaders::RemoveHeaderLine(const std::string& name,
std::string old_header_name;
std::string old_header_value;
while (EnumerateHeaderLines(&iter, &old_header_name, &old_header_value)) {
- std::string old_header_name_lowercase(name);
- base::StringToLowerASCII(&old_header_name_lowercase);
-
+ std::string old_header_name_lowercase = base::ToLowerASCII(old_header_name);
if (name_lowercase == old_header_name_lowercase &&
value == old_header_value)
continue;
@@ -475,7 +466,7 @@ void HttpResponseHeaders::GetNormalizedHeaders(std::string* output) const {
DCHECK(!parsed_[i].is_continuation());
std::string name(parsed_[i].name_begin, parsed_[i].name_end);
- std::string lower_name = base::StringToLowerASCII(name);
+ std::string lower_name = base::ToLowerASCII(name);
iter = headers_map.find(lower_name);
if (iter == headers_map.end()) {
@@ -603,9 +594,7 @@ bool HttpResponseHeaders::HasHeaderValue(const base::StringPiece& name,
void* iter = NULL;
std::string temp;
while (EnumerateHeader(&iter, name, &temp)) {
- if (value.size() == temp.size() &&
- std::equal(temp.begin(), temp.end(), value.begin(),
- base::CaseInsensitiveCompare<char>()))
+ if (base::EqualsCaseInsensitiveASCII(value, temp))
return true;
}
return false;
@@ -633,7 +622,8 @@ HttpVersion HttpResponseHeaders::ParseVersion(
// TODO: (1*DIGIT apparently means one or more digits, but we only handle 1).
// TODO: handle leading zeros, which is allowed by the rfc1616 sec 3.1.
- if ((line_end - p < 4) || !base::LowerCaseEqualsASCII(p, p + 4, "http")) {
+ if (!base::StartsWith(base::StringPiece(line_begin, line_end), "http",
+ base::CompareCase::INSENSITIVE_ASCII)) {
DVLOG(1) << "missing status line";
return HttpVersion();
}
@@ -743,11 +733,8 @@ size_t HttpResponseHeaders::FindHeader(size_t from,
for (size_t i = from; i < parsed_.size(); ++i) {
if (parsed_[i].is_continuation())
continue;
- const std::string::const_iterator& name_begin = parsed_[i].name_begin;
- const std::string::const_iterator& name_end = parsed_[i].name_end;
- if (static_cast<size_t>(name_end - name_begin) == search.size() &&
- std::equal(name_begin, name_end, search.begin(),
- base::CaseInsensitiveCompare<char>()))
+ base::StringPiece name(parsed_[i].name_begin, parsed_[i].name_end);
+ if (base::EqualsCaseInsensitiveASCII(search, name))
return i;
}
@@ -764,8 +751,8 @@ bool HttpResponseHeaders::GetCacheControlDirective(const StringPiece& directive,
void* iter = NULL;
while (EnumerateHeader(&iter, name, &value)) {
if (value.size() > directive_size + 1 &&
- base::LowerCaseEqualsASCII(
- value.begin(), value.begin() + directive_size, directive.begin()) &&
+ base::StartsWith(value, directive,
+ base::CompareCase::INSENSITIVE_ASCII) &&
value[directive_size] == '=') {
int64 seconds;
base::StringToInt64(
@@ -849,9 +836,8 @@ void HttpResponseHeaders::AddNonCacheableHeaders(HeaderSet* result) const {
// assuming the header is not empty, lowercase and insert into set
if (item_end > item) {
- std::string name(&*item, item_end - item);
- base::StringToLowerASCII(&name);
- result->insert(name);
+ result->insert(
+ base::ToLowerASCII(base::StringPiece(&*item, item_end - item)));
}
// Continue to next item.
@@ -1309,8 +1295,9 @@ bool HttpResponseHeaders::GetContentRange(int64* first_byte_position,
std::string::const_iterator content_range_spec_end =
content_range_spec.begin() + space_position;
HttpUtil::TrimLWS(&content_range_spec_begin, &content_range_spec_end);
- if (!base::LowerCaseEqualsASCII(content_range_spec_begin,
- content_range_spec_end, "bytes")) {
+ if (!base::LowerCaseEqualsASCII(
+ base::StringPiece(content_range_spec_begin, content_range_spec_end),
+ "bytes")) {
return false;
}
@@ -1373,8 +1360,9 @@ bool HttpResponseHeaders::GetContentRange(int64* first_byte_position,
content_range_spec.end();
HttpUtil::TrimLWS(&instance_length_begin, &instance_length_end);
- if (base::LowerCaseEqualsASCII(instance_length_begin, instance_length_end,
- "*")) {
+ if (base::StartsWith(
+ base::StringPiece(instance_length_begin, instance_length_end), "*",
+ base::CompareCase::SENSITIVE)) {
return false;
} else if (!base::StringToInt64(StringPiece(instance_length_begin,
instance_length_end),
diff --git a/chromium/net/http/http_response_headers_unittest.cc b/chromium/net/http/http_response_headers_unittest.cc
index 0184885dcd3..35a63608c05 100644
--- a/chromium/net/http/http_response_headers_unittest.cc
+++ b/chromium/net/http/http_response_headers_unittest.cc
@@ -467,8 +467,8 @@ const struct PersistData persistence_tests[] = {
"Strict-Transport-Security: max-age=1576800\n"
"Bar: 1\n"
"Public-Key-Pins: max-age=100000; "
- "pin-sha1=\"ObT42aoSpAqWdY9WfRfL7i0HsVk=\";"
- "pin-sha1=\"7kW49EVwZG0hSNx41ZO/fUPN0ek=\"",
+ "pin-sha256=\"1111111111111111111111111111111111111111111=\";"
+ "pin-sha256=\"2222222222222222222222222222222222222222222=\"",
"HTTP/1.1 200 OK\n"
"Bar: 1\n"},
diff --git a/chromium/net/http/http_response_info.cc b/chromium/net/http/http_response_info.cc
index dbfb62e11bb..fa9d63cccb4 100644
--- a/chromium/net/http/http_response_info.cc
+++ b/chromium/net/http/http_response_info.cc
@@ -93,6 +93,9 @@ enum {
RESPONSE_INFO_UNUSED_SINCE_PREFETCH = 1 << 21,
+ // This bit is set if the response has a key-exchange-info field at the end.
+ RESPONSE_INFO_HAS_KEY_EXCHANGE_INFO = 1 << 22,
+
// TODO(darin): Add other bits to indicate alternate request methods.
// For now, we don't support storing those.
};
@@ -106,8 +109,8 @@ HttpResponseInfo::HttpResponseInfo()
was_fetched_via_proxy(false),
did_use_http_auth(false),
unused_since_prefetch(false),
- connection_info(CONNECTION_INFO_UNKNOWN) {
-}
+ async_revalidation_required(false),
+ connection_info(CONNECTION_INFO_UNKNOWN) {}
HttpResponseInfo::HttpResponseInfo(const HttpResponseInfo& rhs)
: was_cached(rhs.was_cached),
@@ -119,6 +122,7 @@ HttpResponseInfo::HttpResponseInfo(const HttpResponseInfo& rhs)
proxy_server(rhs.proxy_server),
did_use_http_auth(rhs.did_use_http_auth),
unused_since_prefetch(rhs.unused_since_prefetch),
+ async_revalidation_required(rhs.async_revalidation_required),
socket_address(rhs.socket_address),
npn_negotiated_protocol(rhs.npn_negotiated_protocol),
connection_info(rhs.connection_info),
@@ -129,8 +133,7 @@ HttpResponseInfo::HttpResponseInfo(const HttpResponseInfo& rhs)
ssl_info(rhs.ssl_info),
headers(rhs.headers),
vary_data(rhs.vary_data),
- metadata(rhs.metadata) {
-}
+ metadata(rhs.metadata) {}
HttpResponseInfo::~HttpResponseInfo() {
}
@@ -145,6 +148,7 @@ HttpResponseInfo& HttpResponseInfo::operator=(const HttpResponseInfo& rhs) {
was_fetched_via_proxy = rhs.was_fetched_via_proxy;
did_use_http_auth = rhs.did_use_http_auth;
unused_since_prefetch = rhs.unused_since_prefetch;
+ async_revalidation_required = rhs.async_revalidation_required;
socket_address = rhs.socket_address;
npn_negotiated_protocol = rhs.npn_negotiated_protocol;
connection_info = rhs.connection_info;
@@ -272,6 +276,14 @@ bool HttpResponseInfo::InitFromPickle(const base::Pickle& pickle,
}
}
+ // Read key_exchange_info
+ if (flags & RESPONSE_INFO_HAS_KEY_EXCHANGE_INFO) {
+ int key_exchange_info;
+ if (!iter.ReadInt(&key_exchange_info))
+ return false;
+ ssl_info.key_exchange_info = key_exchange_info;
+ }
+
was_fetched_via_spdy = (flags & RESPONSE_INFO_WAS_SPDY) != 0;
was_npn_negotiated = (flags & RESPONSE_INFO_WAS_NPN) != 0;
@@ -296,6 +308,8 @@ void HttpResponseInfo::Persist(base::Pickle* pickle,
flags |= RESPONSE_INFO_HAS_CERT_STATUS;
if (ssl_info.security_bits != -1)
flags |= RESPONSE_INFO_HAS_SECURITY_BITS;
+ if (ssl_info.key_exchange_info != 0)
+ flags |= RESPONSE_INFO_HAS_KEY_EXCHANGE_INFO;
if (ssl_info.connection_status != 0)
flags |= RESPONSE_INFO_HAS_SSL_CONNECTION_STATUS;
}
@@ -367,6 +381,9 @@ void HttpResponseInfo::Persist(base::Pickle* pickle,
if (connection_info != CONNECTION_INFO_UNKNOWN)
pickle->WriteInt(static_cast<int>(connection_info));
+
+ if (ssl_info.is_valid() && ssl_info.key_exchange_info != 0)
+ pickle->WriteInt(ssl_info.key_exchange_info);
}
HttpResponseInfo::ConnectionInfo HttpResponseInfo::ConnectionInfoFromNextProto(
@@ -377,8 +394,6 @@ HttpResponseInfo::ConnectionInfo HttpResponseInfo::ConnectionInfoFromNextProto(
case kProtoSPDY3:
case kProtoSPDY31:
return CONNECTION_INFO_SPDY3;
- case kProtoHTTP2_14:
- return CONNECTION_INFO_HTTP2_14;
case kProtoHTTP2:
return CONNECTION_INFO_HTTP2;
case kProtoQUIC1SPDY3:
@@ -405,15 +420,12 @@ std::string HttpResponseInfo::ConnectionInfoToString(
return "spdy/2";
case CONNECTION_INFO_SPDY3:
return "spdy/3";
+ // Since ConnectionInfo is persisted to disk, deprecated values have to be
+ // handled. Note that h2-14 and h2-15 are essentially wire compatible with
+ // h2.
+ // Intentional fallthrough.
case CONNECTION_INFO_HTTP2_14:
- // For internal consistency, HTTP/2 is named SPDY4 within Chromium.
- // This is the HTTP/2 draft-14 identifier.
- return "h2-14";
case CONNECTION_INFO_HTTP2_15:
- // Since ConnectionInfo is persisted to disk, this value has to be
- // handled, but h2-15 is removed. Note that h2-14 and h2-15 are wire
- // compatible for all practical purposes.
- return "h2-14";
case CONNECTION_INFO_HTTP2:
return "h2";
case CONNECTION_INFO_QUIC1_SPDY3:
diff --git a/chromium/net/http/http_response_info.h b/chromium/net/http/http_response_info.h
index 1ce64f82698..dd1b3da351e 100644
--- a/chromium/net/http/http_response_info.h
+++ b/chromium/net/http/http_response_info.h
@@ -106,6 +106,11 @@ class NET_EXPORT HttpResponseInfo {
// used since.
bool unused_since_prefetch;
+ // True if this resource is stale and requires async revalidation.
+ // This value is not persisted by Persist(); it is only ever set when the
+ // response is retrieved from the cache.
+ bool async_revalidation_required;
+
// Remote address of the socket which fetched this resource.
//
// NOTE: If the response was served from the cache (was_cached is true),
diff --git a/chromium/net/http/http_response_info_unittest.cc b/chromium/net/http/http_response_info_unittest.cc
index ef7d4118eac..d27fb1c8ff7 100644
--- a/chromium/net/http/http_response_info_unittest.cc
+++ b/chromium/net/http/http_response_info_unittest.cc
@@ -52,6 +52,30 @@ TEST_F(HttpResponseInfoTest, UnusedSincePrefetchPersistTrue) {
EXPECT_TRUE(restored_response_info.unused_since_prefetch);
}
+TEST_F(HttpResponseInfoTest, AsyncRevalidationRequiredDefault) {
+ EXPECT_FALSE(response_info_.async_revalidation_required);
+}
+
+TEST_F(HttpResponseInfoTest, AsyncRevalidationRequiredCopy) {
+ response_info_.async_revalidation_required = true;
+ net::HttpResponseInfo response_info_clone(response_info_);
+ EXPECT_TRUE(response_info_clone.async_revalidation_required);
+}
+
+TEST_F(HttpResponseInfoTest, AsyncRevalidationRequiredAssign) {
+ response_info_.async_revalidation_required = true;
+ net::HttpResponseInfo response_info_clone;
+ response_info_clone = response_info_;
+ EXPECT_TRUE(response_info_clone.async_revalidation_required);
+}
+
+TEST_F(HttpResponseInfoTest, AsyncRevalidationRequiredNotPersisted) {
+ response_info_.async_revalidation_required = true;
+ net::HttpResponseInfo restored_response_info;
+ PickleAndRestore(response_info_, &restored_response_info);
+ EXPECT_FALSE(restored_response_info.async_revalidation_required);
+}
+
} // namespace
} // namespace net
diff --git a/chromium/net/http/http_security_headers.cc b/chromium/net/http/http_security_headers.cc
index d95e5878d7c..b99b206c3f3 100644
--- a/chromium/net/http/http_security_headers.cc
+++ b/chromium/net/http/http_security_headers.cc
@@ -5,15 +5,19 @@
#include "base/base64.h"
#include "base/basictypes.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h"
#include "net/http/http_security_headers.h"
#include "net/http/http_util.h"
+#include "url/gurl.h"
namespace net {
namespace {
+enum MaxAgeParsing { REQUIRE_MAX_AGE, DO_NOT_REQUIRE_MAX_AGE };
+
static_assert(kMaxHSTSAgeSecs <= kuint32max, "kMaxHSTSAgeSecs too large");
// MaxAgeToInt converts a string representation of a "whole number" of
@@ -23,7 +27,10 @@ static_assert(kMaxHSTSAgeSecs <= kuint32max, "kMaxHSTSAgeSecs too large");
bool MaxAgeToInt(std::string::const_iterator begin,
std::string::const_iterator end,
uint32* result) {
- const std::string s(begin, end);
+ const base::StringPiece s(begin, end);
+ if (s.empty())
+ return false;
+
int64 i = 0;
// Return false on any StringToInt64 parse errors *except* for
@@ -92,42 +99,16 @@ bool IsPinListValid(const HashValueVector& pins,
HashesIntersect(pins, from_cert_chain);
}
-std::string Strip(const std::string& source) {
- if (source.empty())
- return source;
-
- std::string::const_iterator start = source.begin();
- std::string::const_iterator end = source.end();
- HttpUtil::TrimLWS(&start, &end);
- return std::string(start, end);
-}
-
-typedef std::pair<std::string, std::string> StringPair;
-
-StringPair Split(const std::string& source, char delimiter) {
- StringPair pair;
- size_t point = source.find(delimiter);
-
- pair.first = source.substr(0, point);
- if (std::string::npos != point)
- pair.second = source.substr(point + 1);
-
- return pair;
-}
-
-bool ParseAndAppendPin(const std::string& value,
+bool ParseAndAppendPin(std::string::const_iterator begin,
+ std::string::const_iterator end,
HashValueTag tag,
HashValueVector* hashes) {
- // Pins are always quoted.
- if (value.empty() || !HttpUtil::IsQuote(value[0]))
+ const base::StringPiece value(begin, end);
+ if (value.empty())
return false;
- std::string unquoted = HttpUtil::Unquote(value);
- if (unquoted.empty())
- return false;
-
std::string decoded;
- if (!base::Base64Decode(unquoted, &decoded))
+ if (!base::Base64Decode(value, &decoded))
return false;
HashValue hash(tag);
@@ -139,6 +120,79 @@ bool ParseAndAppendPin(const std::string& value,
return true;
}
+bool ParseHPKPHeaderImpl(const std::string& value,
+ MaxAgeParsing max_age_status,
+ base::TimeDelta* max_age,
+ bool* include_subdomains,
+ HashValueVector* hashes,
+ GURL* report_uri) {
+ bool parsed_max_age = false;
+ bool include_subdomains_candidate = false;
+ uint32 max_age_candidate = 0;
+ GURL parsed_report_uri;
+ HashValueVector pins;
+ bool require_max_age = max_age_status == REQUIRE_MAX_AGE;
+
+ HttpUtil::NameValuePairsIterator name_value_pairs(
+ value.begin(), value.end(), ';',
+ HttpUtil::NameValuePairsIterator::VALUES_OPTIONAL);
+
+ while (name_value_pairs.GetNext()) {
+ if (base::LowerCaseEqualsASCII(
+ base::StringPiece(name_value_pairs.name_begin(),
+ name_value_pairs.name_end()),
+ "max-age")) {
+ if (!MaxAgeToInt(name_value_pairs.value_begin(),
+ name_value_pairs.value_end(), &max_age_candidate)) {
+ return false;
+ }
+ parsed_max_age = true;
+ } else if (base::LowerCaseEqualsASCII(
+ base::StringPiece(name_value_pairs.name_begin(),
+ name_value_pairs.name_end()),
+ "pin-sha256")) {
+ // Pins are always quoted.
+ if (!name_value_pairs.value_is_quoted() ||
+ !ParseAndAppendPin(name_value_pairs.value_begin(),
+ name_value_pairs.value_end(), HASH_VALUE_SHA256,
+ &pins)) {
+ return false;
+ }
+ } else if (base::LowerCaseEqualsASCII(
+ base::StringPiece(name_value_pairs.name_begin(),
+ name_value_pairs.name_end()),
+ "includesubdomains")) {
+ include_subdomains_candidate = true;
+ } else if (base::LowerCaseEqualsASCII(
+ base::StringPiece(name_value_pairs.name_begin(),
+ name_value_pairs.name_end()),
+ "report-uri")) {
+ // report-uris are always quoted.
+ if (!name_value_pairs.value_is_quoted())
+ return false;
+
+ parsed_report_uri = GURL(name_value_pairs.value());
+ if (parsed_report_uri.is_empty() || !parsed_report_uri.is_valid())
+ return false;
+ } else {
+ // Silently ignore unknown directives for forward compatibility.
+ }
+ }
+
+ if (!name_value_pairs.valid())
+ return false;
+
+ if (!parsed_max_age && require_max_age)
+ return false;
+
+ *max_age = base::TimeDelta::FromSeconds(max_age_candidate);
+ *include_subdomains = include_subdomains_candidate;
+ hashes->swap(pins);
+ *report_uri = parsed_report_uri;
+
+ return true;
+}
+
} // namespace
// Parse the Strict-Transport-Security header, as currently defined in
@@ -276,59 +330,48 @@ bool ParseHSTSHeader(const std::string& value,
// "Public-Key-Pins" ":"
// "max-age" "=" delta-seconds ";"
// "pin-" algo "=" base64 [ ";" ... ]
+// [ ";" "includeSubdomains" ]
+// [ ";" "report-uri" "=" uri-reference ]
bool ParseHPKPHeader(const std::string& value,
const HashValueVector& chain_hashes,
base::TimeDelta* max_age,
bool* include_subdomains,
- HashValueVector* hashes) {
- bool parsed_max_age = false;
- bool include_subdomains_candidate = false;
- uint32 max_age_candidate = 0;
- HashValueVector pins;
-
- std::string source = value;
-
- while (!source.empty()) {
- StringPair semicolon = Split(source, ';');
- semicolon.first = Strip(semicolon.first);
- semicolon.second = Strip(semicolon.second);
- StringPair equals = Split(semicolon.first, '=');
- equals.first = Strip(equals.first);
- equals.second = Strip(equals.second);
-
- if (base::LowerCaseEqualsASCII(equals.first, "max-age")) {
- if (equals.second.empty() ||
- !MaxAgeToInt(equals.second.begin(), equals.second.end(),
- &max_age_candidate)) {
- return false;
- }
- parsed_max_age = true;
- } else if (base::LowerCaseEqualsASCII(equals.first, "pin-sha1")) {
- if (!ParseAndAppendPin(equals.second, HASH_VALUE_SHA1, &pins))
- return false;
- } else if (base::LowerCaseEqualsASCII(equals.first, "pin-sha256")) {
- if (!ParseAndAppendPin(equals.second, HASH_VALUE_SHA256, &pins))
- return false;
- } else if (base::LowerCaseEqualsASCII(equals.first, "includesubdomains")) {
- include_subdomains_candidate = true;
- } else {
- // Silently ignore unknown directives for forward compatibility.
- }
-
- source = semicolon.second;
- }
-
- if (!parsed_max_age)
+ HashValueVector* hashes,
+ GURL* report_uri) {
+ base::TimeDelta candidate_max_age;
+ bool candidate_include_subdomains;
+ HashValueVector candidate_hashes;
+ GURL candidate_report_uri;
+
+ if (!ParseHPKPHeaderImpl(value, REQUIRE_MAX_AGE, &candidate_max_age,
+ &candidate_include_subdomains, &candidate_hashes,
+ &candidate_report_uri)) {
return false;
+ }
- if (!IsPinListValid(pins, chain_hashes))
+ if (!IsPinListValid(candidate_hashes, chain_hashes))
return false;
- *max_age = base::TimeDelta::FromSeconds(max_age_candidate);
- *include_subdomains = include_subdomains_candidate;
- hashes->swap(pins);
-
+ *max_age = candidate_max_age;
+ *include_subdomains = candidate_include_subdomains;
+ hashes->swap(candidate_hashes);
+ *report_uri = candidate_report_uri;
return true;
}
+// "Public-Key-Pins-Report-Only" ":"
+// [ "max-age" "=" delta-seconds ";" ]
+// "pin-" algo "=" base64 [ ";" ... ]
+// [ ";" "includeSubdomains" ]
+// [ ";" "report-uri" "=" uri-reference ]
+bool ParseHPKPReportOnlyHeader(const std::string& value,
+ bool* include_subdomains,
+ HashValueVector* hashes,
+ GURL* report_uri) {
+ // max-age is irrelevant for Report-Only headers.
+ base::TimeDelta unused_max_age;
+ return ParseHPKPHeaderImpl(value, DO_NOT_REQUIRE_MAX_AGE, &unused_max_age,
+ include_subdomains, hashes, report_uri);
+}
+
} // namespace net
diff --git a/chromium/net/http/http_security_headers.h b/chromium/net/http/http_security_headers.h
index 12e6be9000a..f54df691fae 100644
--- a/chromium/net/http/http_security_headers.h
+++ b/chromium/net/http/http_security_headers.h
@@ -8,12 +8,13 @@
#include <string>
#include "base/basictypes.h"
-#include "base/gtest_prod_util.h"
#include "base/time/time.h"
#include "base/values.h"
#include "net/base/hash_value.h"
#include "net/base/net_export.h"
+class GURL;
+
namespace net {
const int64 kMaxHSTSAgeSecs = 86400 * 365; // 1 year
@@ -31,9 +32,9 @@ bool NET_EXPORT_PRIVATE ParseHSTSHeader(const std::string& value,
bool* include_subdomains);
// Parses |value| as a Public-Key-Pins header value. If successful, returns
-// true and populates the |*max_age|, |*include_subdomains|, and |*hashes|
-// values. Otherwise returns false and leaves the output parameters
-// unchanged.
+// true and populates the |*max_age|, |*include_subdomains|, |*hashes|, and
+// |*report_uri| values. Otherwise returns false and leaves the output
+// parameters unchanged.
//
// value is the right-hand side of:
//
@@ -41,6 +42,7 @@ bool NET_EXPORT_PRIVATE ParseHSTSHeader(const std::string& value,
// "max-age" "=" delta-seconds ";"
// "pin-" algo "=" base64 [ ";" ... ]
// [ ";" "includeSubdomains" ]
+// [ ";" "report-uri" "=" uri-reference ]
//
// For this function to return true, the key hashes specified by the HPKP
// header must pass two additional checks. There MUST be at least one key
@@ -52,8 +54,26 @@ bool NET_EXPORT_PRIVATE ParseHPKPHeader(const std::string& value,
const HashValueVector& chain_hashes,
base::TimeDelta* max_age,
bool* include_subdomains,
- HashValueVector* hashes);
+ HashValueVector* hashes,
+ GURL* report_uri);
+// Parses |value| as a Public-Key-Pins-Report-Only header value. If
+// successful, returns true and populates the |*include_subdomains|,
+// |*hashes|, and |*report_uri| values. Otherwise returns false and
+// leaves the output parameters unchanged.
+//
+// value is the right-hand side of:
+//
+// "Public-Key-Pins-Report-Only" ":"
+// [ "max-age" "=" delta-seconds ";" ]
+// "pin-" algo "=" base64 [ ";" ... ]
+// [ ";" "includeSubdomains" ]
+// [ ";" "report-uri" "=" uri-reference ]
+//
+bool NET_EXPORT_PRIVATE ParseHPKPReportOnlyHeader(const std::string& value,
+ bool* include_subdomains,
+ HashValueVector* hashes,
+ GURL* report_uri);
} // namespace net
#endif // NET_HTTP_HTTP_SECURITY_HEADERS_H_
diff --git a/chromium/net/http/http_security_headers_unittest.cc b/chromium/net/http/http_security_headers_unittest.cc
index 0dd3020481e..4a510f2f11d 100644
--- a/chromium/net/http/http_security_headers_unittest.cc
+++ b/chromium/net/http/http_security_headers_unittest.cc
@@ -6,9 +6,9 @@
#include <algorithm>
#include "base/base64.h"
-#include "base/sha1.h"
#include "base/strings/string_piece.h"
#include "crypto/sha2.h"
+#include "net/base/host_port_pair.h"
#include "net/base/test_completion_callback.h"
#include "net/http/http_security_headers.h"
#include "net/http/http_util.h"
@@ -35,9 +35,6 @@ std::string GetTestPinImpl(uint8 label, HashValueTag tag, bool quoted) {
std::string ret;
switch (hash_value.tag) {
- case HASH_VALUE_SHA1:
- ret = "pin-sha1=";
- break;
case HASH_VALUE_SHA256:
ret = "pin-sha256=";
break;
@@ -63,6 +60,39 @@ std::string GetTestPinUnquoted(uint8 label, HashValueTag tag) {
};
+// Parses the given header |value| as both a Public-Key-Pins-Report-Only
+// and Public-Key-Pins header. Returns true if the value parses
+// successfully for both header types, and if the parsed hashes and
+// report_uri match for both header types.
+bool ParseAsHPKPHeader(const std::string& value,
+ const HashValueVector& chain_hashes,
+ base::TimeDelta* max_age,
+ bool* include_subdomains,
+ HashValueVector* hashes,
+ GURL* report_uri) {
+ GURL report_only_uri;
+ bool report_only_include_subdomains;
+ HashValueVector report_only_hashes;
+ if (!ParseHPKPReportOnlyHeader(value, &report_only_include_subdomains,
+ &report_only_hashes, &report_only_uri)) {
+ return false;
+ }
+
+ bool result = ParseHPKPHeader(value, chain_hashes, max_age,
+ include_subdomains, hashes, report_uri);
+ if (!result || report_only_include_subdomains != *include_subdomains ||
+ report_only_uri != *report_uri ||
+ report_only_hashes.size() != hashes->size()) {
+ return false;
+ }
+
+ for (size_t i = 0; i < report_only_hashes.size(); i++) {
+ if (!(*hashes)[i].Equals(report_only_hashes[i]))
+ return false;
+ }
+
+ return true;
+}
class HttpSecurityHeadersTest : public testing::Test {
};
@@ -152,6 +182,7 @@ static void TestBogusPinsHeaders(HashValueTag tag) {
bool include_subdomains;
HashValueVector hashes;
HashValueVector chain_hashes;
+ GURL report_uri;
// Set some fake "chain" hashes
chain_hashes.push_back(GetTestHashValue(1, tag));
@@ -163,78 +194,105 @@ static void TestBogusPinsHeaders(HashValueTag tag) {
std::string good_pin_unquoted = GetTestPinUnquoted(2, tag);
std::string backup_pin = GetTestPin(4, tag);
- EXPECT_FALSE(ParseHPKPHeader(std::string(), chain_hashes, &max_age,
- &include_subdomains, &hashes));
- EXPECT_FALSE(ParseHPKPHeader(" ", chain_hashes, &max_age,
- &include_subdomains, &hashes));
- EXPECT_FALSE(ParseHPKPHeader("abc", chain_hashes, &max_age,
- &include_subdomains, &hashes));
- EXPECT_FALSE(ParseHPKPHeader(" abc", chain_hashes, &max_age,
- &include_subdomains, &hashes));
- EXPECT_FALSE(ParseHPKPHeader(" abc ", chain_hashes, &max_age,
- &include_subdomains, &hashes));
- EXPECT_FALSE(ParseHPKPHeader("max-age", chain_hashes, &max_age,
- &include_subdomains, &hashes));
- EXPECT_FALSE(ParseHPKPHeader(" max-age", chain_hashes, &max_age,
- &include_subdomains, &hashes));
- EXPECT_FALSE(ParseHPKPHeader(" max-age ", chain_hashes, &max_age,
- &include_subdomains, &hashes));
- EXPECT_FALSE(ParseHPKPHeader("max-age=", chain_hashes, &max_age,
- &include_subdomains, &hashes));
- EXPECT_FALSE(ParseHPKPHeader(" max-age=", chain_hashes, &max_age,
- &include_subdomains, &hashes));
- EXPECT_FALSE(ParseHPKPHeader(" max-age =", chain_hashes, &max_age,
- &include_subdomains, &hashes));
- EXPECT_FALSE(ParseHPKPHeader(" max-age= ", chain_hashes, &max_age,
- &include_subdomains, &hashes));
- EXPECT_FALSE(ParseHPKPHeader(" max-age = ", chain_hashes,
- &max_age, &include_subdomains, &hashes));
- EXPECT_FALSE(ParseHPKPHeader(" max-age = xy", chain_hashes,
- &max_age, &include_subdomains, &hashes));
- EXPECT_FALSE(ParseHPKPHeader(" max-age = 3488a923",
- chain_hashes, &max_age, &include_subdomains,
- &hashes));
- EXPECT_FALSE(ParseHPKPHeader("max-age=3488a923 ", chain_hashes,
- &max_age, &include_subdomains, &hashes));
- EXPECT_FALSE(ParseHPKPHeader("max-ag=3488923pins=" + good_pin + "," +
- backup_pin,
- chain_hashes, &max_age, &include_subdomains,
- &hashes));
- EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923" + backup_pin,
- chain_hashes, &max_age, &include_subdomains,
- &hashes));
- EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923; " + backup_pin,
- chain_hashes, &max_age, &include_subdomains,
- &hashes));
- EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923; " + backup_pin + ";" +
- backup_pin,
- chain_hashes, &max_age, &include_subdomains,
- &hashes));
- EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923; " + good_pin + ";" +
- good_pin,
- chain_hashes, &max_age, &include_subdomains,
- &hashes));
- EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923; " + good_pin,
- chain_hashes, &max_age, &include_subdomains,
- &hashes));
- EXPECT_FALSE(ParseHPKPHeader("max-age==3488923", chain_hashes, &max_age,
- &include_subdomains, &hashes));
- EXPECT_FALSE(ParseHPKPHeader("amax-age=3488923", chain_hashes, &max_age,
- &include_subdomains, &hashes));
- EXPECT_FALSE(ParseHPKPHeader("max-age=-3488923", chain_hashes, &max_age,
- &include_subdomains, &hashes));
- EXPECT_FALSE(ParseHPKPHeader("max-age=3488923;", chain_hashes, &max_age,
- &include_subdomains, &hashes));
- EXPECT_FALSE(ParseHPKPHeader("max-age=3488923 e", chain_hashes,
- &max_age, &include_subdomains, &hashes));
- EXPECT_FALSE(ParseHPKPHeader("max-age=3488923 includesubdomain",
- chain_hashes, &max_age, &include_subdomains,
- &hashes));
- EXPECT_FALSE(ParseHPKPHeader("max-age=34889.23", chain_hashes, &max_age,
- &include_subdomains, &hashes));
- EXPECT_FALSE(
- ParseHPKPHeader("max-age=243; " + good_pin_unquoted + ";" + backup_pin,
- chain_hashes, &max_age, &include_subdomains, &hashes));
+ EXPECT_FALSE(ParseAsHPKPHeader(std::string(), chain_hashes, &max_age,
+ &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader(" ", chain_hashes, &max_age,
+ &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader("abc", chain_hashes, &max_age,
+ &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader(" abc", chain_hashes, &max_age,
+ &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader(" abc ", chain_hashes, &max_age,
+ &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader("max-age", chain_hashes, &max_age,
+ &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader(" max-age", chain_hashes, &max_age,
+ &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader(" max-age ", chain_hashes, &max_age,
+ &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader("max-age=", chain_hashes, &max_age,
+ &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader(" max-age=", chain_hashes, &max_age,
+ &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader(" max-age =", chain_hashes, &max_age,
+ &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader(" max-age= ", chain_hashes, &max_age,
+ &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader(" max-age = ", chain_hashes, &max_age,
+ &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader(" max-age = xy", chain_hashes, &max_age,
+ &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader(" max-age = 3488a923", chain_hashes,
+ &max_age, &include_subdomains, &hashes,
+ &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader("max-age=3488a923 ", chain_hashes, &max_age,
+ &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader(
+ "max-ag=3488923pins=" + good_pin + "," + backup_pin, chain_hashes,
+ &max_age, &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader(
+ "max-age=3488923;pins=" + good_pin + "," + backup_pin +
+ "report-uri=\"http://foo.com\"",
+ chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader("max-aged=3488923" + backup_pin, chain_hashes,
+ &max_age, &include_subdomains, &hashes,
+ &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader("max-aged=3488923; " + backup_pin,
+ chain_hashes, &max_age, &include_subdomains,
+ &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader(
+ "max-aged=3488923; " + backup_pin + ";" + backup_pin, chain_hashes,
+ &max_age, &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader(
+ "max-aged=3488923; " + good_pin + ";" + good_pin, chain_hashes, &max_age,
+ &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader("max-aged=3488923; " + good_pin, chain_hashes,
+ &max_age, &include_subdomains, &hashes,
+ &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader("max-age==3488923", chain_hashes, &max_age,
+ &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader("amax-age=3488923", chain_hashes, &max_age,
+ &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader("max-age=-3488923", chain_hashes, &max_age,
+ &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader("max-age=3488923;", chain_hashes, &max_age,
+ &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader("max-age=3488923 e", chain_hashes,
+ &max_age, &include_subdomains, &hashes,
+ &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader("max-age=3488923 includesubdomain",
+ chain_hashes, &max_age, &include_subdomains,
+ &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader(
+ "max-age=3488923 report-uri=\"http://foo.com\"", chain_hashes,
+ &max_age, &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader("max-age=34889.23", chain_hashes, &max_age,
+ &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader(
+ "max-age=243; " + good_pin_unquoted + ";" + backup_pin, chain_hashes,
+ &max_age, &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader(
+ "max-age=243; " + good_pin + ";" + backup_pin + ";report-uri=;",
+ chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader("max-age=243; " + good_pin + ";" + backup_pin +
+ ";report-uri=http://foo.com;",
+ chain_hashes, &max_age, &include_subdomains,
+ &hashes, &report_uri));
+ EXPECT_FALSE(ParseAsHPKPHeader(
+ "max-age=243; " + good_pin + ";" + backup_pin + ";report-uri=''",
+ chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri));
+
+ // Test that the parser rejects misquoted strings.
+ EXPECT_FALSE(ParseAsHPKPHeader(
+ "max-age=999; " + backup_pin + "; " + good_pin +
+ "; report-uri=\"http://foo;bar\'",
+ chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri));
+
+ // Test that the parser rejects invalid report-uris.
+ EXPECT_FALSE(ParseAsHPKPHeader("max-age=999; " + backup_pin + "; " +
+ good_pin + "; report-uri=\"foo;bar\'",
+ chain_hashes, &max_age, &include_subdomains,
+ &hashes, &report_uri));
// Check the out args were not updated by checking the default
// values for its predictable fields.
@@ -405,6 +463,8 @@ static void TestValidPKPHeaders(HashValueTag tag) {
bool include_subdomains;
HashValueVector hashes;
HashValueVector chain_hashes;
+ GURL expect_report_uri;
+ GURL report_uri;
// Set some fake "chain" hashes into chain_hashes
chain_hashes.push_back(GetTestHashValue(1, tag));
@@ -416,106 +476,175 @@ static void TestValidPKPHeaders(HashValueTag tag) {
std::string good_pin2 = GetTestPin(3, tag);
std::string backup_pin = GetTestPin(4, tag);
- EXPECT_TRUE(ParseHPKPHeader(
- "max-age=243; " + good_pin + ";" + backup_pin,
- chain_hashes, &max_age, &include_subdomains, &hashes));
+ EXPECT_TRUE(ParseAsHPKPHeader("max-age=243; " + good_pin + ";" + backup_pin,
+ chain_hashes, &max_age, &include_subdomains,
+ &hashes, &report_uri));
expect_max_age = base::TimeDelta::FromSeconds(243);
EXPECT_EQ(expect_max_age, max_age);
EXPECT_FALSE(include_subdomains);
+ EXPECT_TRUE(report_uri.is_empty());
- EXPECT_TRUE(ParseHPKPHeader(
- " " + good_pin + "; " + backup_pin + " ; Max-agE = 567",
- chain_hashes, &max_age, &include_subdomains, &hashes));
+ EXPECT_TRUE(ParseAsHPKPHeader("max-age=243; " + good_pin + ";" + backup_pin +
+ "; report-uri= \"http://example.test/foo\"",
+ chain_hashes, &max_age, &include_subdomains,
+ &hashes, &report_uri));
+ expect_max_age = base::TimeDelta::FromSeconds(243);
+ expect_report_uri = GURL("http://example.test/foo");
+ EXPECT_EQ(expect_max_age, max_age);
+ EXPECT_FALSE(include_subdomains);
+ EXPECT_EQ(expect_report_uri, report_uri);
+
+ EXPECT_TRUE(ParseAsHPKPHeader(
+ " " + good_pin + "; " + backup_pin +
+ " ; Max-agE = 567; repOrT-URi = \"http://example.test/foo\"",
+ chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri));
expect_max_age = base::TimeDelta::FromSeconds(567);
+ expect_report_uri = GURL("http://example.test/foo");
EXPECT_EQ(expect_max_age, max_age);
EXPECT_FALSE(include_subdomains);
+ EXPECT_EQ(expect_report_uri, report_uri);
- EXPECT_TRUE(ParseHPKPHeader(
- "includeSubDOMAINS;" + good_pin + ";" + backup_pin +
- " ; mAx-aGe = 890 ",
- chain_hashes, &max_age, &include_subdomains, &hashes));
+ EXPECT_TRUE(ParseAsHPKPHeader("includeSubDOMAINS;" + good_pin + ";" +
+ backup_pin + " ; mAx-aGe = 890 ",
+ chain_hashes, &max_age, &include_subdomains,
+ &hashes, &report_uri));
expect_max_age = base::TimeDelta::FromSeconds(890);
EXPECT_EQ(expect_max_age, max_age);
EXPECT_TRUE(include_subdomains);
- EXPECT_TRUE(ParseHPKPHeader(
- good_pin + ";" + backup_pin + "; max-age=123;IGNORED;",
- chain_hashes, &max_age, &include_subdomains, &hashes));
+ EXPECT_TRUE(ParseAsHPKPHeader(
+ good_pin + ";" + backup_pin + "; max-age=123;IGNORED;", chain_hashes,
+ &max_age, &include_subdomains, &hashes, &report_uri));
expect_max_age = base::TimeDelta::FromSeconds(123);
EXPECT_EQ(expect_max_age, max_age);
EXPECT_FALSE(include_subdomains);
- EXPECT_TRUE(ParseHPKPHeader(
- "max-age=394082;" + backup_pin + ";" + good_pin + "; ",
- chain_hashes, &max_age, &include_subdomains, &hashes));
+ EXPECT_TRUE(ParseAsHPKPHeader(
+ "max-age=394082;" + backup_pin + ";" + good_pin + "; ", chain_hashes,
+ &max_age, &include_subdomains, &hashes, &report_uri));
expect_max_age = base::TimeDelta::FromSeconds(394082);
EXPECT_EQ(expect_max_age, max_age);
EXPECT_FALSE(include_subdomains);
- EXPECT_TRUE(ParseHPKPHeader(
- "max-age=39408299 ;" + backup_pin + ";" + good_pin + "; ",
- chain_hashes, &max_age, &include_subdomains, &hashes));
+ EXPECT_TRUE(ParseAsHPKPHeader(
+ "max-age=39408299 ;" + backup_pin + ";" + good_pin + "; ", chain_hashes,
+ &max_age, &include_subdomains, &hashes, &report_uri));
expect_max_age = base::TimeDelta::FromSeconds(
std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(39408299))));
EXPECT_EQ(expect_max_age, max_age);
EXPECT_FALSE(include_subdomains);
- EXPECT_TRUE(ParseHPKPHeader(
+ EXPECT_TRUE(ParseAsHPKPHeader(
"max-age=39408038 ; cybers=39408038 ; includeSubdomains; " +
good_pin + ";" + backup_pin + "; ",
- chain_hashes, &max_age, &include_subdomains, &hashes));
+ chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri));
expect_max_age = base::TimeDelta::FromSeconds(
std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(394082038))));
EXPECT_EQ(expect_max_age, max_age);
EXPECT_TRUE(include_subdomains);
- EXPECT_TRUE(ParseHPKPHeader(
- " max-age=0 ; " + good_pin + ";" + backup_pin,
- chain_hashes, &max_age, &include_subdomains, &hashes));
+ EXPECT_TRUE(ParseAsHPKPHeader(
+ " max-age=0 ; " + good_pin + ";" + backup_pin, chain_hashes, &max_age,
+ &include_subdomains, &hashes, &report_uri));
expect_max_age = base::TimeDelta::FromSeconds(0);
EXPECT_EQ(expect_max_age, max_age);
EXPECT_FALSE(include_subdomains);
- EXPECT_TRUE(ParseHPKPHeader(
+ EXPECT_TRUE(ParseAsHPKPHeader(
" max-age=0 ; includeSubdomains; " + good_pin + ";" + backup_pin,
- chain_hashes, &max_age, &include_subdomains, &hashes));
+ chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri));
expect_max_age = base::TimeDelta::FromSeconds(0);
EXPECT_EQ(expect_max_age, max_age);
EXPECT_TRUE(include_subdomains);
- EXPECT_TRUE(ParseHPKPHeader(
+ EXPECT_TRUE(ParseAsHPKPHeader(
" max-age=999999999999999999999999999999999999999999999 ; " +
backup_pin + ";" + good_pin + "; ",
- chain_hashes, &max_age, &include_subdomains, &hashes));
+ chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri));
+ expect_max_age = base::TimeDelta::FromSeconds(kMaxHSTSAgeSecs);
+ EXPECT_EQ(expect_max_age, max_age);
+ EXPECT_FALSE(include_subdomains);
+
+ EXPECT_TRUE(ParseAsHPKPHeader(
+ " max-age=999999999999999999999999999999999999999999999 ; " +
+ backup_pin + ";" + good_pin +
+ "; report-uri=\"http://example.test/foo\"",
+ chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri));
expect_max_age = base::TimeDelta::FromSeconds(kMaxHSTSAgeSecs);
+ expect_report_uri = GURL("http://example.test/foo");
EXPECT_EQ(expect_max_age, max_age);
EXPECT_FALSE(include_subdomains);
+ EXPECT_EQ(expect_report_uri, report_uri);
// Test that parsing a different header resets the hashes.
hashes.clear();
- EXPECT_TRUE(ParseHPKPHeader(
- " max-age=999; " +
- backup_pin + ";" + good_pin + "; ",
- chain_hashes, &max_age, &include_subdomains, &hashes));
+ EXPECT_TRUE(ParseAsHPKPHeader(
+ " max-age=999; " + backup_pin + ";" + good_pin + "; ", chain_hashes,
+ &max_age, &include_subdomains, &hashes, &report_uri));
EXPECT_EQ(2u, hashes.size());
- EXPECT_TRUE(ParseHPKPHeader(
+ EXPECT_TRUE(ParseAsHPKPHeader(
" max-age=999; " + backup_pin + ";" + good_pin2 + "; ", chain_hashes,
- &max_age, &include_subdomains, &hashes));
+ &max_age, &include_subdomains, &hashes, &report_uri));
EXPECT_EQ(2u, hashes.size());
-}
-TEST_F(HttpSecurityHeadersTest, BogusPinsHeadersSHA1) {
- TestBogusPinsHeaders(HASH_VALUE_SHA1);
+ // Test that the parser correctly parses an unencoded ';' inside a
+ // quoted report-uri.
+ EXPECT_TRUE(ParseAsHPKPHeader("max-age=999; " + backup_pin + "; " + good_pin +
+ "; report-uri=\"http://foo.com/?;bar\"",
+ chain_hashes, &max_age, &include_subdomains,
+ &hashes, &report_uri));
+ expect_max_age = base::TimeDelta::FromSeconds(999);
+ expect_report_uri = GURL("http://foo.com/?;bar");
+ EXPECT_EQ(expect_max_age, max_age);
+ EXPECT_FALSE(include_subdomains);
+ EXPECT_EQ(expect_report_uri, report_uri);
+
+ // Test that the parser correctly parses a report-uri with a >0x7f
+ // character.
+ std::string uri = "http://foo.com/";
+ uri += char(0x7f);
+ expect_report_uri = GURL(uri);
+ EXPECT_TRUE(ParseAsHPKPHeader("max-age=999; " + backup_pin + "; " + good_pin +
+ "; report-uri=\"" + uri + "\"",
+ chain_hashes, &max_age, &include_subdomains,
+ &hashes, &report_uri));
+ expect_max_age = base::TimeDelta::FromSeconds(999);
+ EXPECT_EQ(expect_max_age, max_age);
+ EXPECT_FALSE(include_subdomains);
+ EXPECT_EQ(expect_report_uri, report_uri);
+
+ // Test that the parser allows quoted max-age values.
+ EXPECT_TRUE(ParseAsHPKPHeader(
+ "max-age='999'; " + backup_pin + "; " + good_pin, chain_hashes, &max_age,
+ &include_subdomains, &hashes, &report_uri));
+ expect_max_age = base::TimeDelta::FromSeconds(999);
+ EXPECT_EQ(expect_max_age, max_age);
+ EXPECT_FALSE(include_subdomains);
+
+ // Test that the parser handles escaped values.
+ expect_report_uri = GURL("http://foo.com'a");
+ EXPECT_TRUE(ParseAsHPKPHeader("max-age=999; " + backup_pin + "; " + good_pin +
+ "; report-uri='http://foo.com\\'\\a'",
+ chain_hashes, &max_age, &include_subdomains,
+ &hashes, &report_uri));
+ expect_max_age = base::TimeDelta::FromSeconds(999);
+ EXPECT_EQ(expect_max_age, max_age);
+ EXPECT_FALSE(include_subdomains);
+ EXPECT_EQ(expect_report_uri, report_uri);
+
+ // Test that the parser does not require max-age for Report-Only
+ // headers.
+ expect_report_uri = GURL("http://foo.com");
+ EXPECT_TRUE(ParseHPKPReportOnlyHeader(
+ backup_pin + "; " + good_pin + "; report-uri='http://foo.com'",
+ &include_subdomains, &hashes, &report_uri));
+ EXPECT_EQ(expect_report_uri, report_uri);
}
TEST_F(HttpSecurityHeadersTest, BogusPinsHeadersSHA256) {
TestBogusPinsHeaders(HASH_VALUE_SHA256);
}
-TEST_F(HttpSecurityHeadersTest, ValidPKPHeadersSHA1) {
- TestValidPKPHeaders(HASH_VALUE_SHA1);
-}
-
TEST_F(HttpSecurityHeadersTest, ValidPKPHeadersSHA256) {
TestValidPKPHeaders(HASH_VALUE_SHA256);
}
@@ -534,11 +663,13 @@ TEST_F(HttpSecurityHeadersTest, UpdateDynamicPKPOnly) {
HashValueVector saved_hashes = static_pkp_state.spki_hashes;
// Add a header, which should only update the dynamic state.
- HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1);
- HashValue backup_hash = GetTestHashValue(2, HASH_VALUE_SHA1);
- std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1);
- std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1);
- std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin;
+ HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA256);
+ HashValue backup_hash = GetTestHashValue(2, HASH_VALUE_SHA256);
+ std::string good_pin = GetTestPin(1, HASH_VALUE_SHA256);
+ std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA256);
+ GURL report_uri("http://google.com");
+ std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin +
+ ";report-uri=\"" + report_uri.spec() + "\"";
// Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
SSLInfo ssl_info;
@@ -560,6 +691,7 @@ TEST_F(HttpSecurityHeadersTest, UpdateDynamicPKPOnly) {
TransportSecurityState::PKPState dynamic_pkp_state;
EXPECT_TRUE(state.GetDynamicPKPState(domain, &dynamic_pkp_state));
EXPECT_EQ(2UL, dynamic_pkp_state.spki_hashes.size());
+ EXPECT_EQ(report_uri, dynamic_pkp_state.report_uri);
HashValueVector::const_iterator hash = std::find_if(
dynamic_pkp_state.spki_hashes.begin(),
@@ -577,12 +709,15 @@ TEST_F(HttpSecurityHeadersTest, UpdateDynamicPKPOnly) {
hashes.push_back(good_hash);
std::string failure_log;
const bool is_issued_by_known_root = true;
+ HostPortPair domain_port(domain, 443);
EXPECT_TRUE(state.CheckPublicKeyPins(
- domain, is_issued_by_known_root, hashes, &failure_log));
+ domain_port, is_issued_by_known_root, hashes, nullptr, nullptr,
+ TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log));
TransportSecurityState::PKPState new_dynamic_pkp_state;
EXPECT_TRUE(state.GetDynamicPKPState(domain, &new_dynamic_pkp_state));
EXPECT_EQ(2UL, new_dynamic_pkp_state.spki_hashes.size());
+ EXPECT_EQ(report_uri, new_dynamic_pkp_state.report_uri);
hash = std::find_if(new_dynamic_pkp_state.spki_hashes.begin(),
new_dynamic_pkp_state.spki_hashes.end(),
@@ -609,9 +744,9 @@ TEST_F(HttpSecurityHeadersTest, UpdateDynamicPKPMaxAge0) {
HashValueVector saved_hashes = static_pkp_state.spki_hashes;
// Add a header, which should only update the dynamic state.
- HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1);
- std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1);
- std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1);
+ HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA256);
+ std::string good_pin = GetTestPin(1, HASH_VALUE_SHA256);
+ std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA256);
std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin;
// Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
@@ -669,9 +804,11 @@ TEST_F(HttpSecurityHeadersTest, UpdateDynamicPKPMaxAge0) {
new_static_pkp_state2.spki_hashes[2].data()[0] ^= 0x80;
const bool is_issued_by_known_root = true;
- EXPECT_FALSE(state.CheckPublicKeyPins(domain, is_issued_by_known_root,
- new_static_pkp_state2.spki_hashes,
- &failure_log));
+ HostPortPair domain_port(domain, 443);
+ EXPECT_FALSE(state.CheckPublicKeyPins(
+ domain_port, is_issued_by_known_root, new_static_pkp_state2.spki_hashes,
+ nullptr, nullptr, TransportSecurityState::DISABLE_PIN_REPORTS,
+ &failure_log));
EXPECT_NE(0UL, failure_log.length());
}
@@ -703,15 +840,15 @@ TEST_F(HttpSecurityHeadersTest, NoClobberPins) {
EXPECT_TRUE(state.ShouldUpgradeToSSL(domain));
std::string failure_log;
const bool is_issued_by_known_root = true;
- EXPECT_TRUE(state.CheckPublicKeyPins(domain,
- is_issued_by_known_root,
- saved_hashes,
- &failure_log));
+ HostPortPair domain_port(domain, 443);
+ EXPECT_TRUE(state.CheckPublicKeyPins(
+ domain_port, is_issued_by_known_root, saved_hashes, nullptr, nullptr,
+ TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log));
// Add an HPKP header, which should only update the dynamic state.
- HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1);
- std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1);
- std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1);
+ HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA256);
+ std::string good_pin = GetTestPin(1, HASH_VALUE_SHA256);
+ std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA256);
std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin;
// Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
@@ -726,10 +863,9 @@ TEST_F(HttpSecurityHeadersTest, NoClobberPins) {
EXPECT_TRUE(state.ShouldUpgradeToSSL(domain));
// The dynamic pins, which do not match |saved_hashes|, should take
// precedence over the static pins and cause the check to fail.
- EXPECT_FALSE(state.CheckPublicKeyPins(domain,
- is_issued_by_known_root,
- saved_hashes,
- &failure_log));
+ EXPECT_FALSE(state.CheckPublicKeyPins(
+ domain_port, is_issued_by_known_root, saved_hashes, nullptr, nullptr,
+ TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log));
}
// Tests that seeing an invalid HPKP header leaves the existing one alone.
@@ -753,9 +889,10 @@ TEST_F(HttpSecurityHeadersTest, IgnoreInvalidHeaders) {
EXPECT_TRUE(state.HasPublicKeyPins("example.com"));
std::string failure_log;
bool is_issued_by_known_root = true;
- EXPECT_TRUE(state.CheckPublicKeyPins("example.com", is_issued_by_known_root,
- ssl_info.public_key_hashes,
- &failure_log));
+ HostPortPair domain_port("example.com", 443);
+ EXPECT_TRUE(state.CheckPublicKeyPins(
+ domain_port, is_issued_by_known_root, ssl_info.public_key_hashes, nullptr,
+ nullptr, TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log));
// Now assert an invalid one. This should fail.
EXPECT_FALSE(state.AddHPKPHeader(
@@ -764,9 +901,9 @@ TEST_F(HttpSecurityHeadersTest, IgnoreInvalidHeaders) {
// The old pins must still exist.
EXPECT_TRUE(state.HasPublicKeyPins("example.com"));
- EXPECT_TRUE(state.CheckPublicKeyPins("example.com", is_issued_by_known_root,
- ssl_info.public_key_hashes,
- &failure_log));
+ EXPECT_TRUE(state.CheckPublicKeyPins(
+ domain_port, is_issued_by_known_root, ssl_info.public_key_hashes, nullptr,
+ nullptr, TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log));
}
}; // namespace net
diff --git a/chromium/net/http/http_server_properties.cc b/chromium/net/http/http_server_properties.cc
index 8d4ef947317..1e3ccd234f0 100644
--- a/chromium/net/http/http_server_properties.cc
+++ b/chromium/net/http/http_server_properties.cc
@@ -13,6 +13,7 @@
namespace net {
const char kAlternateProtocolHeader[] = "Alternate-Protocol";
+const char kAlternativeServiceHeader[] = "Alt-Svc";
namespace {
@@ -22,7 +23,6 @@ const char* const kAlternateProtocolStrings[] = {
"npn-spdy/2",
"npn-spdy/3",
"npn-spdy/3.1",
- "npn-h2-14", // HTTP/2 draft-14. Called SPDY4 internally.
"npn-h2",
"quic"};
@@ -53,7 +53,6 @@ const char* AlternateProtocolToString(AlternateProtocol protocol) {
case DEPRECATED_NPN_SPDY_2:
case NPN_SPDY_3:
case NPN_SPDY_3_1:
- case NPN_HTTP_2_14:
case NPN_HTTP_2:
case QUIC:
DCHECK(IsAlternateProtocolValid(protocol));
@@ -84,8 +83,6 @@ AlternateProtocol AlternateProtocolFromNextProto(NextProto next_proto) {
return NPN_SPDY_3;
case kProtoSPDY31:
return NPN_SPDY_3_1;
- case kProtoHTTP2_14:
- return NPN_HTTP_2_14;
case kProtoHTTP2:
return NPN_HTTP_2;
case kProtoQUIC1SPDY3:
diff --git a/chromium/net/http/http_server_properties.h b/chromium/net/http/http_server_properties.h
index 780dd005e67..2e50f5ede71 100644
--- a/chromium/net/http/http_server_properties.h
+++ b/chromium/net/http/http_server_properties.h
@@ -67,7 +67,6 @@ enum AlternateProtocol {
NPN_SPDY_MINIMUM_VERSION = DEPRECATED_NPN_SPDY_2,
NPN_SPDY_3,
NPN_SPDY_3_1,
- NPN_HTTP_2_14, // HTTP/2 draft-14
NPN_HTTP_2, // HTTP/2
NPN_SPDY_MAXIMUM_VERSION = NPN_HTTP_2,
QUIC,
@@ -143,14 +142,20 @@ struct NET_EXPORT AlternativeServiceInfo {
AlternativeServiceInfo() : alternative_service(), probability(0.0) {}
AlternativeServiceInfo(const AlternativeService& alternative_service,
- double probability)
- : alternative_service(alternative_service), probability(probability) {}
+ double probability,
+ base::Time expiration)
+ : alternative_service(alternative_service),
+ probability(probability),
+ expiration(expiration) {}
AlternativeServiceInfo(AlternateProtocol protocol,
const std::string& host,
uint16 port,
- double probability)
- : alternative_service(protocol, host, port), probability(probability) {}
+ double probability,
+ base::Time expiration)
+ : alternative_service(protocol, host, port),
+ probability(probability),
+ expiration(expiration) {}
AlternativeServiceInfo(
const AlternativeServiceInfo& alternative_service_info) = default;
@@ -159,7 +164,7 @@ struct NET_EXPORT AlternativeServiceInfo {
bool operator==(const AlternativeServiceInfo& other) const {
return alternative_service == other.alternative_service &&
- probability == other.probability;
+ probability == other.probability && expiration == other.expiration;
}
bool operator!=(const AlternativeServiceInfo& other) const {
@@ -170,6 +175,7 @@ struct NET_EXPORT AlternativeServiceInfo {
AlternativeService alternative_service;
double probability;
+ base::Time expiration;
};
struct NET_EXPORT SupportsQuic {
@@ -209,6 +215,7 @@ typedef base::MRUCache<HostPortPair, SettingsMap> SpdySettingsMap;
typedef base::MRUCache<HostPortPair, ServerNetworkStats> ServerNetworkStatsMap;
extern const char kAlternateProtocolHeader[];
+extern const char kAlternativeServiceHeader[];
// The interface for setting/retrieving the HTTP server properties.
// Currently, this class manages servers':
@@ -264,7 +271,8 @@ class NET_EXPORT HttpServerProperties {
virtual bool SetAlternativeService(
const HostPortPair& origin,
const AlternativeService& alternative_service,
- double alternative_probability) = 0;
+ double alternative_probability,
+ base::Time expiration) = 0;
// Set alternative services for |origin|. Previous alternative services for
// |origin| are discarded.
diff --git a/chromium/net/http/http_server_properties_impl.cc b/chromium/net/http/http_server_properties_impl.cc
index 15871b53086..6278f3627bf 100644
--- a/chromium/net/http/http_server_properties_impl.cc
+++ b/chromium/net/http/http_server_properties_impl.cc
@@ -83,6 +83,7 @@ void HttpServerPropertiesImpl::InitializeAlternativeServiceServers(
for (AlternativeServiceMap::reverse_iterator input_it =
alternative_service_map->rbegin();
input_it != alternative_service_map->rend(); ++input_it) {
+ DCHECK(!input_it->second.empty());
AlternativeServiceMap::iterator output_it =
alternative_service_map_.Peek(input_it->first);
if (output_it == alternative_service_map_.end()) {
@@ -117,7 +118,8 @@ void HttpServerPropertiesImpl::InitializeAlternativeServiceServers(
for (AlternativeServiceMap::const_iterator it =
alternative_service_map_.begin();
it != alternative_service_map_.end(); ++it) {
- if (base::EndsWith(it->first.host(), canonical_suffixes_[i], false)) {
+ if (base::EndsWith(it->first.host(), canonical_suffixes_[i],
+ base::CompareCase::INSENSITIVE_ASCII)) {
canonical_host_to_origin_map_[canonical_host] = it->first;
break;
}
@@ -260,7 +262,8 @@ std::string HttpServerPropertiesImpl::GetCanonicalSuffix(
// suffix.
for (size_t i = 0; i < canonical_suffixes_.size(); ++i) {
std::string canonical_suffix = canonical_suffixes_[i];
- if (base::EndsWith(host, canonical_suffixes_[i], false)) {
+ if (base::EndsWith(host, canonical_suffixes_[i],
+ base::CompareCase::INSENSITIVE_ASCII)) {
return canonical_suffix;
}
}
@@ -272,20 +275,37 @@ AlternativeServiceVector HttpServerPropertiesImpl::GetAlternativeServices(
// Copy alternative services with probability greater than or equal to the
// threshold into |alternative_services_above_threshold|.
AlternativeServiceVector alternative_services_above_threshold;
- AlternativeServiceMap::const_iterator it =
- alternative_service_map_.Get(origin);
- if (it != alternative_service_map_.end()) {
- for (const AlternativeServiceInfo& alternative_service_info : it->second) {
- if (alternative_service_info.probability <
- alternative_service_probability_threshold_) {
+ const base::Time now = base::Time::Now();
+ AlternativeServiceMap::iterator map_it = alternative_service_map_.Get(origin);
+ if (map_it != alternative_service_map_.end()) {
+ for (AlternativeServiceInfoVector::iterator it = map_it->second.begin();
+ it != map_it->second.end();) {
+ if (it->expiration < now) {
+ it = map_it->second.erase(it);
continue;
}
- AlternativeService alternative_service(
- alternative_service_info.alternative_service);
+ if (it->probability < alternative_service_probability_threshold_) {
+ ++it;
+ continue;
+ }
+ AlternativeService alternative_service(it->alternative_service);
if (alternative_service.host.empty()) {
alternative_service.host = origin.host();
}
+ // If the alternative service is equivalent to the origin (same host, same
+ // port, and both TCP), then there is already a Job for it, so do not
+ // return it here.
+ if (origin.Equals(alternative_service.host_port_pair()) &&
+ NPN_SPDY_MINIMUM_VERSION <= alternative_service.protocol &&
+ alternative_service.protocol <= NPN_SPDY_MAXIMUM_VERSION) {
+ ++it;
+ continue;
+ }
alternative_services_above_threshold.push_back(alternative_service);
+ ++it;
+ }
+ if (map_it->second.empty()) {
+ alternative_service_map_.Erase(map_it);
}
return alternative_services_above_threshold;
}
@@ -294,27 +314,37 @@ AlternativeServiceVector HttpServerPropertiesImpl::GetAlternativeServices(
if (canonical == canonical_host_to_origin_map_.end()) {
return AlternativeServiceVector();
}
- it = alternative_service_map_.Get(canonical->second);
- if (it == alternative_service_map_.end()) {
+ map_it = alternative_service_map_.Get(canonical->second);
+ if (map_it == alternative_service_map_.end()) {
return AlternativeServiceVector();
}
- for (const AlternativeServiceInfo& alternative_service_info : it->second) {
- if (alternative_service_info.probability <
- alternative_service_probability_threshold_) {
+ for (AlternativeServiceInfoVector::iterator it = map_it->second.begin();
+ it != map_it->second.end();) {
+ if (it->expiration < now) {
+ it = map_it->second.erase(it);
continue;
}
- AlternativeService alternative_service(
- alternative_service_info.alternative_service);
+ if (it->probability < alternative_service_probability_threshold_) {
+ ++it;
+ continue;
+ }
+ AlternativeService alternative_service(it->alternative_service);
if (alternative_service.host.empty()) {
alternative_service.host = canonical->second.host();
if (IsAlternativeServiceBroken(alternative_service)) {
+ ++it;
continue;
}
alternative_service.host = origin.host();
} else if (IsAlternativeServiceBroken(alternative_service)) {
+ ++it;
continue;
}
alternative_services_above_threshold.push_back(alternative_service);
+ ++it;
+ }
+ if (map_it->second.empty()) {
+ alternative_service_map_.Erase(map_it);
}
return alternative_services_above_threshold;
}
@@ -322,11 +352,13 @@ AlternativeServiceVector HttpServerPropertiesImpl::GetAlternativeServices(
bool HttpServerPropertiesImpl::SetAlternativeService(
const HostPortPair& origin,
const AlternativeService& alternative_service,
- double alternative_probability) {
+ double alternative_probability,
+ base::Time expiration) {
return SetAlternativeServices(
origin, AlternativeServiceInfoVector(
- /*size=*/1, AlternativeServiceInfo(alternative_service,
- alternative_probability)));
+ /*size=*/1,
+ AlternativeServiceInfo(alternative_service,
+ alternative_probability, expiration)));
}
bool HttpServerPropertiesImpl::SetAlternativeServices(
@@ -368,7 +400,8 @@ bool HttpServerPropertiesImpl::SetAlternativeServices(
// canonical host.
for (size_t i = 0; i < canonical_suffixes_.size(); ++i) {
std::string canonical_suffix = canonical_suffixes_[i];
- if (base::EndsWith(origin.host(), canonical_suffixes_[i], false)) {
+ if (base::EndsWith(origin.host(), canonical_suffixes_[i],
+ base::CompareCase::INSENSITIVE_ASCII)) {
HostPortPair canonical_host(canonical_suffix, origin.port());
canonical_host_to_origin_map_[canonical_host] = origin;
break;
@@ -611,7 +644,8 @@ HttpServerPropertiesImpl::CanonicalHostMap::const_iterator
HttpServerPropertiesImpl::GetCanonicalHost(HostPortPair server) const {
for (size_t i = 0; i < canonical_suffixes_.size(); ++i) {
std::string canonical_suffix = canonical_suffixes_[i];
- if (base::EndsWith(server.host(), canonical_suffixes_[i], false)) {
+ if (base::EndsWith(server.host(), canonical_suffixes_[i],
+ base::CompareCase::INSENSITIVE_ASCII)) {
HostPortPair canonical_host(canonical_suffix, server.port());
return canonical_host_to_origin_map_.find(canonical_host);
}
@@ -641,11 +675,38 @@ void HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings() {
break;
}
- const AlternativeService alternative_service = it->first;
+ const AlternativeService expired_alternative_service = it->first;
broken_alternative_services_.erase(it);
- // TODO(bnc): Make sure broken alternative services are not in the mapping.
- ClearAlternativeServices(
- HostPortPair(alternative_service.host, alternative_service.port));
+
+ // Remove every occurrence of |expired_alternative_service| from
+ // |alternative_service_map_|.
+ for (AlternativeServiceMap::iterator map_it =
+ alternative_service_map_.begin();
+ map_it != alternative_service_map_.end();) {
+ for (AlternativeServiceInfoVector::iterator it = map_it->second.begin();
+ it != map_it->second.end();) {
+ AlternativeService alternative_service(it->alternative_service);
+ // Empty hostname in map means hostname of key: substitute before
+ // comparing to |expired_alternative_service|.
+ if (alternative_service.host.empty()) {
+ alternative_service.host = map_it->first.host();
+ }
+ if (alternative_service == expired_alternative_service) {
+ it = map_it->second.erase(it);
+ continue;
+ }
+ ++it;
+ }
+ // If an origin has an empty list of alternative services, then remove it
+ // from both |canonical_host_to_origin_map_| and
+ // |alternative_service_map_|.
+ if (map_it->second.empty()) {
+ RemoveCanonicalHost(map_it->first);
+ map_it = alternative_service_map_.Erase(map_it);
+ continue;
+ }
+ ++map_it;
+ }
}
ScheduleBrokenAlternateProtocolMappingsExpiration();
}
diff --git a/chromium/net/http/http_server_properties_impl.h b/chromium/net/http/http_server_properties_impl.h
index 3abf5c83f4c..d6ee31a684f 100644
--- a/chromium/net/http/http_server_properties_impl.h
+++ b/chromium/net/http/http_server_properties_impl.h
@@ -13,7 +13,6 @@
#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
-#include "base/gtest_prod_util.h"
#include "base/threading/non_thread_safe.h"
#include "base/values.h"
#include "net/base/host_port_pair.h"
@@ -91,7 +90,8 @@ class NET_EXPORT HttpServerPropertiesImpl
const HostPortPair& origin) override;
bool SetAlternativeService(const HostPortPair& origin,
const AlternativeService& alternative_service,
- double alternative_probability) override;
+ double alternative_probability,
+ base::Time expiration) override;
bool SetAlternativeServices(const HostPortPair& origin,
const AlternativeServiceInfoVector&
alternative_service_info_vector) override;
diff --git a/chromium/net/http/http_server_properties_impl_unittest.cc b/chromium/net/http/http_server_properties_impl_unittest.cc
index 23cb395d84c..e354b77c53d 100644
--- a/chromium/net/http/http_server_properties_impl_unittest.cc
+++ b/chromium/net/http/http_server_properties_impl_unittest.cc
@@ -55,6 +55,15 @@ class HttpServerPropertiesImplTest : public testing::Test {
return !alternative_service_vector.empty();
}
+ bool SetAlternativeService(const HostPortPair& origin,
+ const AlternativeService& alternative_service,
+ double alternative_probability) {
+ const base::Time expiration =
+ base::Time::Now() + base::TimeDelta::FromDays(1);
+ return impl_.SetAlternativeService(origin, alternative_service,
+ alternative_probability, expiration);
+ }
+
HttpServerPropertiesImpl impl_;
};
@@ -124,14 +133,14 @@ TEST_F(SpdyServerPropertiesTest, SupportsRequestPriorityTest) {
// Add www.youtube.com:443 as supporting QUIC.
HostPortPair quic_server_youtube("www.youtube.com", 443);
const AlternativeService alternative_service1(QUIC, "www.youtube.com", 443);
- impl_.SetAlternativeService(quic_server_youtube, alternative_service1, 1.0);
+ SetAlternativeService(quic_server_youtube, alternative_service1, 1.0);
EXPECT_TRUE(impl_.SupportsRequestPriority(quic_server_youtube));
// Add www.example.com:443 with two alternative services, one supporting QUIC.
HostPortPair quic_server_example("www.example.com", 443);
const AlternativeService alternative_service2(NPN_HTTP_2, "", 443);
- impl_.SetAlternativeService(quic_server_example, alternative_service2, 1.0);
- impl_.SetAlternativeService(quic_server_example, alternative_service1, 1.0);
+ SetAlternativeService(quic_server_example, alternative_service2, 1.0);
+ SetAlternativeService(quic_server_example, alternative_service1, 1.0);
EXPECT_TRUE(impl_.SupportsRequestPriority(quic_server_example));
// Verify all the entries are the same after additions.
@@ -259,7 +268,7 @@ TEST_F(AlternateProtocolServerPropertiesTest, Basic) {
EXPECT_FALSE(HasAlternativeService(test_host_port_pair));
AlternativeService alternative_service(NPN_HTTP_2, "foo", 443);
- impl_.SetAlternativeService(test_host_port_pair, alternative_service, 1.0);
+ SetAlternativeService(test_host_port_pair, alternative_service, 1.0);
const AlternativeServiceVector alternative_service_vector =
impl_.GetAlternativeServices(test_host_port_pair);
ASSERT_EQ(1u, alternative_service_vector.size());
@@ -269,10 +278,42 @@ TEST_F(AlternateProtocolServerPropertiesTest, Basic) {
EXPECT_FALSE(HasAlternativeService(test_host_port_pair));
}
+TEST_F(AlternateProtocolServerPropertiesTest, ExcludeOrigin) {
+ AlternativeServiceInfoVector alternative_service_info_vector;
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
+ // Same hostname, same port, TCP: should be ignored.
+ AlternativeService alternative_service1(NPN_HTTP_2, "foo", 443);
+ alternative_service_info_vector.push_back(
+ AlternativeServiceInfo(alternative_service1, 1.0, expiration));
+ // Different hostname: GetAlternativeServices should return this one.
+ AlternativeService alternative_service2(NPN_HTTP_2, "bar", 443);
+ alternative_service_info_vector.push_back(
+ AlternativeServiceInfo(alternative_service2, 1.0, expiration));
+ // Different port: GetAlternativeServices should return this one too.
+ AlternativeService alternative_service3(NPN_HTTP_2, "foo", 80);
+ alternative_service_info_vector.push_back(
+ AlternativeServiceInfo(alternative_service3, 1.0, expiration));
+ // QUIC: GetAlternativeServices should return this one too.
+ AlternativeService alternative_service4(QUIC, "foo", 443);
+ alternative_service_info_vector.push_back(
+ AlternativeServiceInfo(alternative_service4, 1.0, expiration));
+
+ HostPortPair test_host_port_pair("foo", 443);
+ impl_.SetAlternativeServices(test_host_port_pair,
+ alternative_service_info_vector);
+
+ const AlternativeServiceVector alternative_service_vector =
+ impl_.GetAlternativeServices(test_host_port_pair);
+ ASSERT_EQ(3u, alternative_service_vector.size());
+ EXPECT_EQ(alternative_service2, alternative_service_vector[0]);
+ EXPECT_EQ(alternative_service3, alternative_service_vector[1]);
+ EXPECT_EQ(alternative_service4, alternative_service_vector[2]);
+}
+
TEST_F(AlternateProtocolServerPropertiesTest, DefaultProbabilityExcluded) {
HostPortPair test_host_port_pair("foo", 80);
const AlternativeService alternative_service(NPN_HTTP_2, "foo", 443);
- impl_.SetAlternativeService(test_host_port_pair, alternative_service, 0.99);
+ SetAlternativeService(test_host_port_pair, alternative_service, 0.99);
EXPECT_FALSE(HasAlternativeService(test_host_port_pair));
}
@@ -283,18 +324,19 @@ TEST_F(AlternateProtocolServerPropertiesTest, Probability) {
impl_.SetAlternativeServiceProbabilityThreshold(0.5);
AlternativeServiceInfoVector alternative_service_info_vector;
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
const AlternativeService alternative_service1(NPN_HTTP_2, "foo", 443);
alternative_service_info_vector.push_back(
- AlternativeServiceInfo(alternative_service1, 0.3));
+ AlternativeServiceInfo(alternative_service1, 0.3, expiration));
const AlternativeService alternative_service2(QUIC, "bar", 123);
alternative_service_info_vector.push_back(
- AlternativeServiceInfo(alternative_service2, 0.7));
+ AlternativeServiceInfo(alternative_service2, 0.7, expiration));
const AlternativeService alternative_service3(NPN_SPDY_3_1, "baz", 443);
alternative_service_info_vector.push_back(
- AlternativeServiceInfo(alternative_service3, 0.4));
+ AlternativeServiceInfo(alternative_service3, 0.4, expiration));
const AlternativeService alternative_service4(NPN_HTTP_2, "qux", 1234);
alternative_service_info_vector.push_back(
- AlternativeServiceInfo(alternative_service4, 0.6));
+ AlternativeServiceInfo(alternative_service4, 0.6, expiration));
HostPortPair test_host_port_pair("foo", 80);
impl_.SetAlternativeServices(test_host_port_pair,
@@ -312,7 +354,7 @@ TEST_F(AlternateProtocolServerPropertiesTest, ProbabilityExcluded) {
HostPortPair test_host_port_pair("foo", 80);
const AlternativeService alternative_service(NPN_HTTP_2, "foo", 443);
- impl_.SetAlternativeService(test_host_port_pair, alternative_service, 0.5);
+ SetAlternativeService(test_host_port_pair, alternative_service, 0.5);
EXPECT_FALSE(HasAlternativeService(test_host_port_pair));
}
@@ -321,18 +363,23 @@ TEST_F(AlternateProtocolServerPropertiesTest, Initialize) {
// and thus will be removed by InitializeAlternativeServiceServers().
HostPortPair test_host_port_pair1("foo1", 80);
const AlternativeService alternative_service1(NPN_HTTP_2, "bar1", 443);
- impl_.SetAlternativeService(test_host_port_pair1, alternative_service1, 1.0);
+ const base::Time now = base::Time::Now();
+ base::Time expiration1 = now + base::TimeDelta::FromDays(1);
+ impl_.SetAlternativeService(test_host_port_pair1, alternative_service1, 1.0,
+ expiration1);
// |test_host_port_pair2| has two alternative services. The broken one will
// remain, the non-broken one will be removed by
// InitializeAlternativeServiceServers().
AlternativeServiceInfoVector alternative_service_info_vector;
const AlternativeService alternative_service2(NPN_SPDY_3_1, "bar2", 443);
+ base::Time expiration2 = now + base::TimeDelta::FromDays(2);
alternative_service_info_vector.push_back(
- AlternativeServiceInfo(alternative_service2, 1.0));
+ AlternativeServiceInfo(alternative_service2, 1.0, expiration2));
const AlternativeService alternative_service3(NPN_SPDY_3_1, "bar3", 1234);
+ base::Time expiration3 = now + base::TimeDelta::FromDays(3);
alternative_service_info_vector.push_back(
- AlternativeServiceInfo(alternative_service3, 0.8));
+ AlternativeServiceInfo(alternative_service3, 0.8, expiration3));
HostPortPair test_host_port_pair2("foo2", 80);
impl_.SetAlternativeServices(test_host_port_pair2,
alternative_service_info_vector);
@@ -343,16 +390,18 @@ TEST_F(AlternateProtocolServerPropertiesTest, Initialize) {
AlternativeServiceMap alternative_service_map(
AlternativeServiceMap::NO_AUTO_EVICT);
const AlternativeService alternative_service4(NPN_HTTP_2, "bar4", 123);
+ base::Time expiration4 = now + base::TimeDelta::FromDays(4);
const AlternativeServiceInfo alternative_service_info1(alternative_service4,
- 0.7);
+ 0.7, expiration4);
alternative_service_map.Put(
test_host_port_pair2,
AlternativeServiceInfoVector(/*size=*/1, alternative_service_info1));
HostPortPair test_host_port_pair3("foo3", 80);
const AlternativeService alternative_service5(NPN_HTTP_2, "bar5", 1234);
+ base::Time expiration5 = now + base::TimeDelta::FromDays(5);
const AlternativeServiceInfo alternative_service_info2(alternative_service5,
- 0.2);
+ 0.2, expiration5);
alternative_service_map.Put(
test_host_port_pair3,
AlternativeServiceInfoVector(/*size=*/1, alternative_service_info2));
@@ -367,13 +416,16 @@ TEST_F(AlternateProtocolServerPropertiesTest, Initialize) {
ASSERT_EQ(1u, map_it->second.size());
EXPECT_EQ(alternative_service5, map_it->second[0].alternative_service);
EXPECT_EQ(0.2, map_it->second[0].probability);
+ EXPECT_EQ(expiration5, map_it->second[0].expiration);
++map_it;
EXPECT_TRUE(map_it->first.Equals(test_host_port_pair2));
ASSERT_EQ(2u, map_it->second.size());
EXPECT_EQ(alternative_service2, map_it->second[0].alternative_service);
EXPECT_EQ(1.0, map_it->second[0].probability);
+ EXPECT_EQ(expiration2, map_it->second[0].expiration);
EXPECT_EQ(alternative_service4, map_it->second[1].alternative_service);
EXPECT_EQ(0.7, map_it->second[1].probability);
+ EXPECT_EQ(expiration4, map_it->second[1].expiration);
}
// Regression test for https://crbug.com/504032:
@@ -385,8 +437,8 @@ TEST_F(AlternateProtocolServerPropertiesTest, InitializeWithEmptyHostname) {
"", 1234);
const AlternativeService alternative_service_with_foo_hostname(NPN_HTTP_2,
"foo", 1234);
- impl_.SetAlternativeService(host_port_pair,
- alternative_service_with_empty_hostname, 1.0);
+ SetAlternativeService(host_port_pair, alternative_service_with_empty_hostname,
+ 1.0);
impl_.MarkAlternativeServiceBroken(alternative_service_with_foo_hostname);
AlternativeServiceMap alternative_service_map(
@@ -402,13 +454,89 @@ TEST_F(AlternateProtocolServerPropertiesTest, InitializeWithEmptyHostname) {
alternative_service_vector[0]);
}
+// Regression test for https://crbug.com/516486:
+// GetAlternativeServices() should remove |alternative_service_map_| elements
+// with empty value.
+TEST_F(AlternateProtocolServerPropertiesTest, EmptyVector) {
+ HostPortPair host_port_pair("foo", 443);
+ const AlternativeService alternative_service(NPN_HTTP_2, "bar", 443);
+ base::Time expiration = base::Time::Now() - base::TimeDelta::FromDays(1);
+ const AlternativeServiceInfo alternative_service_info(alternative_service,
+ 1.0, expiration);
+ AlternativeServiceMap alternative_service_map(
+ AlternativeServiceMap::NO_AUTO_EVICT);
+ alternative_service_map.Put(
+ host_port_pair,
+ AlternativeServiceInfoVector(/*size=*/1, alternative_service_info));
+
+ // Prepare |alternative_service_map_| with a single key that has a single
+ // AlternativeServiceInfo with identical hostname and port.
+ impl_.InitializeAlternativeServiceServers(&alternative_service_map);
+
+ // GetAlternativeServices() should remove such AlternativeServiceInfo from
+ // |alternative_service_map_|, emptying the AlternativeServiceInfoVector
+ // corresponding to |host_port_pair|.
+ AlternativeServiceVector alternative_service_vector =
+ impl_.GetAlternativeServices(host_port_pair);
+ ASSERT_TRUE(alternative_service_vector.empty());
+
+ // GetAlternativeServices() should remove this key from
+ // |alternative_service_map_|, and SetAlternativeServices() should not crash.
+ impl_.SetAlternativeServices(
+ host_port_pair,
+ AlternativeServiceInfoVector(/*size=*/1, alternative_service_info));
+
+ // There should still be no alternative service assigned to |host_port_pair|.
+ alternative_service_vector = impl_.GetAlternativeServices(host_port_pair);
+ ASSERT_TRUE(alternative_service_vector.empty());
+}
+
+// Regression test for https://crbug.com/516486 for the canonical host case.
+TEST_F(AlternateProtocolServerPropertiesTest, EmptyVectorForCanonical) {
+ HostPortPair host_port_pair("foo.c.youtube.com", 443);
+ HostPortPair canonical_host_port_pair("bar.c.youtube.com", 443);
+ const AlternativeService alternative_service(NPN_HTTP_2, "", 443);
+ base::Time expiration = base::Time::Now() - base::TimeDelta::FromDays(1);
+ const AlternativeServiceInfo alternative_service_info(alternative_service,
+ 1.0, expiration);
+ AlternativeServiceMap alternative_service_map(
+ AlternativeServiceMap::NO_AUTO_EVICT);
+ alternative_service_map.Put(
+ canonical_host_port_pair,
+ AlternativeServiceInfoVector(/*size=*/1, alternative_service_info));
+
+ // Prepare |alternative_service_map_| with a single key that has a single
+ // AlternativeServiceInfo with identical hostname and port.
+ impl_.InitializeAlternativeServiceServers(&alternative_service_map);
+
+ // GetAlternativeServices() should remove such AlternativeServiceInfo from
+ // |alternative_service_map_|, emptying the AlternativeServiceInfoVector
+ // corresponding to |canonical_host_port_pair|, even when looking up
+ // alternative services for |host_port_pair|.
+ AlternativeServiceVector alternative_service_vector =
+ impl_.GetAlternativeServices(host_port_pair);
+ ASSERT_TRUE(alternative_service_vector.empty());
+
+ // GetAlternativeServices() should remove this key from
+ // |alternative_service_map_|, and SetAlternativeServices() should not crash.
+ impl_.SetAlternativeServices(
+ canonical_host_port_pair,
+ AlternativeServiceInfoVector(/*size=*/1, alternative_service_info));
+
+ // There should still be no alternative service assigned to
+ // |canonical_host_port_pair|.
+ alternative_service_vector =
+ impl_.GetAlternativeServices(canonical_host_port_pair);
+ ASSERT_TRUE(alternative_service_vector.empty());
+}
+
TEST_F(AlternateProtocolServerPropertiesTest, MRUOfGetAlternativeServices) {
HostPortPair test_host_port_pair1("foo1", 80);
const AlternativeService alternative_service1(NPN_SPDY_3_1, "foo1", 443);
- impl_.SetAlternativeService(test_host_port_pair1, alternative_service1, 1.0);
+ SetAlternativeService(test_host_port_pair1, alternative_service1, 1.0);
HostPortPair test_host_port_pair2("foo2", 80);
const AlternativeService alternative_service2(NPN_HTTP_2, "foo2", 1234);
- impl_.SetAlternativeService(test_host_port_pair2, alternative_service2, 1.0);
+ SetAlternativeService(test_host_port_pair2, alternative_service2, 1.0);
const AlternativeServiceMap& map = impl_.alternative_service_map();
AlternativeServiceMap::const_iterator it = map.begin();
@@ -431,7 +559,7 @@ TEST_F(AlternateProtocolServerPropertiesTest, MRUOfGetAlternativeServices) {
TEST_F(AlternateProtocolServerPropertiesTest, SetBroken) {
HostPortPair test_host_port_pair("foo", 80);
const AlternativeService alternative_service1(NPN_HTTP_2, "foo", 443);
- impl_.SetAlternativeService(test_host_port_pair, alternative_service1, 1.0);
+ SetAlternativeService(test_host_port_pair, alternative_service1, 1.0);
AlternativeServiceVector alternative_service_vector =
impl_.GetAlternativeServices(test_host_port_pair);
ASSERT_EQ(1u, alternative_service_vector.size());
@@ -448,11 +576,12 @@ TEST_F(AlternateProtocolServerPropertiesTest, SetBroken) {
// SetAlternativeServices should add a broken alternative service to the map.
AlternativeServiceInfoVector alternative_service_info_vector;
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
alternative_service_info_vector.push_back(
- AlternativeServiceInfo(alternative_service1, 1.0));
+ AlternativeServiceInfo(alternative_service1, 1.0, expiration));
const AlternativeService alternative_service2(NPN_HTTP_2, "foo", 1234);
alternative_service_info_vector.push_back(
- AlternativeServiceInfo(alternative_service2, 1.0));
+ AlternativeServiceInfo(alternative_service2, 1.0, expiration));
impl_.SetAlternativeServices(test_host_port_pair,
alternative_service_info_vector);
alternative_service_vector =
@@ -464,7 +593,7 @@ TEST_F(AlternateProtocolServerPropertiesTest, SetBroken) {
EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service_vector[1]));
// SetAlternativeService should add a broken alternative service to the map.
- impl_.SetAlternativeService(test_host_port_pair, alternative_service1, 1.0);
+ SetAlternativeService(test_host_port_pair, alternative_service1, 1.0);
alternative_service_vector =
impl_.GetAlternativeServices(test_host_port_pair);
ASSERT_EQ(1u, alternative_service_vector.size());
@@ -472,14 +601,70 @@ TEST_F(AlternateProtocolServerPropertiesTest, SetBroken) {
EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service_vector[0]));
}
+TEST_F(AlternateProtocolServerPropertiesTest, MaxAge) {
+ AlternativeServiceInfoVector alternative_service_info_vector;
+ base::Time now = base::Time::Now();
+ base::TimeDelta one_day = base::TimeDelta::FromDays(1);
+
+ // First alternative service expired one day ago, should not be returned by
+ // GetAlternativeServices().
+ const AlternativeService alternative_service1(NPN_SPDY_3_1, "foo", 443);
+ alternative_service_info_vector.push_back(
+ AlternativeServiceInfo(alternative_service1, 1.0, now - one_day));
+
+ // Second alterrnative service will expire one day from now, should be
+ // returned by GetAlternativeSerices().
+ const AlternativeService alternative_service2(NPN_HTTP_2, "bar", 1234);
+ alternative_service_info_vector.push_back(
+ AlternativeServiceInfo(alternative_service2, 1.0, now + one_day));
+
+ HostPortPair test_host_port_pair("foo", 80);
+ impl_.SetAlternativeServices(test_host_port_pair,
+ alternative_service_info_vector);
+
+ AlternativeServiceVector alternative_service_vector =
+ impl_.GetAlternativeServices(test_host_port_pair);
+ ASSERT_EQ(1u, alternative_service_vector.size());
+ EXPECT_EQ(alternative_service2, alternative_service_vector[0]);
+}
+
+TEST_F(AlternateProtocolServerPropertiesTest, MaxAgeCanonical) {
+ AlternativeServiceInfoVector alternative_service_info_vector;
+ base::Time now = base::Time::Now();
+ base::TimeDelta one_day = base::TimeDelta::FromDays(1);
+
+ // First alternative service expired one day ago, should not be returned by
+ // GetAlternativeServices().
+ const AlternativeService alternative_service1(NPN_SPDY_3_1, "foo", 443);
+ alternative_service_info_vector.push_back(
+ AlternativeServiceInfo(alternative_service1, 1.0, now - one_day));
+
+ // Second alterrnative service will expire one day from now, should be
+ // returned by GetAlternativeSerices().
+ const AlternativeService alternative_service2(NPN_HTTP_2, "bar", 1234);
+ alternative_service_info_vector.push_back(
+ AlternativeServiceInfo(alternative_service2, 1.0, now + one_day));
+
+ HostPortPair canonical_host_port_pair("bar.c.youtube.com", 80);
+ impl_.SetAlternativeServices(canonical_host_port_pair,
+ alternative_service_info_vector);
+
+ HostPortPair test_host_port_pair("foo.c.youtube.com", 80);
+ AlternativeServiceVector alternative_service_vector =
+ impl_.GetAlternativeServices(test_host_port_pair);
+ ASSERT_EQ(1u, alternative_service_vector.size());
+ EXPECT_EQ(alternative_service2, alternative_service_vector[0]);
+}
+
TEST_F(AlternateProtocolServerPropertiesTest, ClearAlternativeServices) {
AlternativeServiceInfoVector alternative_service_info_vector;
const AlternativeService alternative_service1(NPN_SPDY_3_1, "foo", 443);
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
alternative_service_info_vector.push_back(
- AlternativeServiceInfo(alternative_service1, 1.0));
+ AlternativeServiceInfo(alternative_service1, 1.0, expiration));
const AlternativeService alternative_service2(NPN_HTTP_2, "bar", 1234);
alternative_service_info_vector.push_back(
- AlternativeServiceInfo(alternative_service2, 1.0));
+ AlternativeServiceInfo(alternative_service2, 1.0, expiration));
HostPortPair test_host_port_pair("foo", 80);
impl_.SetAlternativeServices(test_host_port_pair,
alternative_service_info_vector);
@@ -504,8 +689,8 @@ TEST_F(AlternateProtocolServerPropertiesTest, BrokenShadowsCanonical) {
HostPortPair canonical_host_port_pair("bar.c.youtube.com", 80);
AlternativeService canonical_alternative_service(QUIC, "bar.c.youtube.com",
1234);
- impl_.SetAlternativeService(canonical_host_port_pair,
- canonical_alternative_service, 1.0);
+ SetAlternativeService(canonical_host_port_pair, canonical_alternative_service,
+ 1.0);
AlternativeServiceVector alternative_service_vector =
impl_.GetAlternativeServices(test_host_port_pair);
ASSERT_EQ(1u, alternative_service_vector.size());
@@ -515,8 +700,7 @@ TEST_F(AlternateProtocolServerPropertiesTest, BrokenShadowsCanonical) {
impl_.MarkAlternativeServiceBroken(broken_alternative_service);
EXPECT_TRUE(impl_.IsAlternativeServiceBroken(broken_alternative_service));
- impl_.SetAlternativeService(test_host_port_pair, broken_alternative_service,
- 1.0);
+ SetAlternativeService(test_host_port_pair, broken_alternative_service, 1.0);
alternative_service_vector =
impl_.GetAlternativeServices(test_host_port_pair);
ASSERT_EQ(1u, alternative_service_vector.size());
@@ -527,7 +711,7 @@ TEST_F(AlternateProtocolServerPropertiesTest, BrokenShadowsCanonical) {
TEST_F(AlternateProtocolServerPropertiesTest, ClearBroken) {
HostPortPair test_host_port_pair("foo", 80);
const AlternativeService alternative_service(NPN_HTTP_2, "foo", 443);
- impl_.SetAlternativeService(test_host_port_pair, alternative_service, 1.0);
+ SetAlternativeService(test_host_port_pair, alternative_service, 1.0);
impl_.MarkAlternativeServiceBroken(alternative_service);
ASSERT_TRUE(HasAlternativeService(test_host_port_pair));
EXPECT_TRUE(impl_.IsAlternativeServiceBroken(alternative_service));
@@ -540,7 +724,7 @@ TEST_F(AlternateProtocolServerPropertiesTest, ClearBroken) {
TEST_F(AlternateProtocolServerPropertiesTest, MarkRecentlyBroken) {
HostPortPair host_port_pair("foo", 80);
const AlternativeService alternative_service(NPN_HTTP_2, "foo", 443);
- impl_.SetAlternativeService(host_port_pair, alternative_service, 1.0);
+ SetAlternativeService(host_port_pair, alternative_service, 1.0);
EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service));
EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
@@ -564,11 +748,12 @@ TEST_F(AlternateProtocolServerPropertiesTest, Canonical) {
AlternativeServiceInfoVector alternative_service_info_vector;
const AlternativeService canonical_alternative_service1(
QUIC, "bar.c.youtube.com", 1234);
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
alternative_service_info_vector.push_back(
- AlternativeServiceInfo(canonical_alternative_service1, 1.0));
+ AlternativeServiceInfo(canonical_alternative_service1, 1.0, expiration));
const AlternativeService canonical_alternative_service2(NPN_HTTP_2, "", 443);
alternative_service_info_vector.push_back(
- AlternativeServiceInfo(canonical_alternative_service2, 1.0));
+ AlternativeServiceInfo(canonical_alternative_service2, 1.0, expiration));
impl_.SetAlternativeServices(canonical_host_port_pair,
alternative_service_info_vector);
@@ -603,8 +788,8 @@ TEST_F(AlternateProtocolServerPropertiesTest, CanonicalBelowThreshold) {
AlternativeService canonical_alternative_service(QUIC, "bar.c.youtube.com",
1234);
- impl_.SetAlternativeService(canonical_host_port_pair,
- canonical_alternative_service, 0.01);
+ SetAlternativeService(canonical_host_port_pair, canonical_alternative_service,
+ 0.01);
EXPECT_FALSE(HasAlternativeService(canonical_host_port_pair));
EXPECT_FALSE(HasAlternativeService(test_host_port_pair));
}
@@ -617,8 +802,8 @@ TEST_F(AlternateProtocolServerPropertiesTest, CanonicalAboveThreshold) {
AlternativeService canonical_alternative_service(QUIC, "bar.c.youtube.com",
1234);
- impl_.SetAlternativeService(canonical_host_port_pair,
- canonical_alternative_service, 0.03);
+ SetAlternativeService(canonical_host_port_pair, canonical_alternative_service,
+ 0.03);
EXPECT_TRUE(HasAlternativeService(canonical_host_port_pair));
EXPECT_TRUE(HasAlternativeService(test_host_port_pair));
}
@@ -629,8 +814,8 @@ TEST_F(AlternateProtocolServerPropertiesTest, ClearCanonical) {
AlternativeService canonical_alternative_service(QUIC, "bar.c.youtube.com",
1234);
- impl_.SetAlternativeService(canonical_host_port_pair,
- canonical_alternative_service, 1.0);
+ SetAlternativeService(canonical_host_port_pair, canonical_alternative_service,
+ 1.0);
impl_.ClearAlternativeServices(canonical_host_port_pair);
EXPECT_FALSE(HasAlternativeService(test_host_port_pair));
}
@@ -641,8 +826,8 @@ TEST_F(AlternateProtocolServerPropertiesTest, CanonicalBroken) {
AlternativeService canonical_alternative_service(QUIC, "bar.c.youtube.com",
1234);
- impl_.SetAlternativeService(canonical_host_port_pair,
- canonical_alternative_service, 1.0);
+ SetAlternativeService(canonical_host_port_pair, canonical_alternative_service,
+ 1.0);
impl_.MarkAlternativeServiceBroken(canonical_alternative_service);
EXPECT_FALSE(HasAlternativeService(test_host_port_pair));
}
@@ -652,7 +837,7 @@ TEST_F(AlternateProtocolServerPropertiesTest, CanonicalOverride) {
HostPortPair test_host_port_pair("foo.c.youtube.com", 80);
HostPortPair bar_host_port_pair("bar.c.youtube.com", 80);
AlternativeService bar_alternative_service(QUIC, "bar.c.youtube.com", 1234);
- impl_.SetAlternativeService(bar_host_port_pair, bar_alternative_service, 1.0);
+ SetAlternativeService(bar_host_port_pair, bar_alternative_service, 1.0);
AlternativeServiceVector alternative_service_vector =
impl_.GetAlternativeServices(test_host_port_pair);
ASSERT_EQ(1u, alternative_service_vector.size());
@@ -660,7 +845,7 @@ TEST_F(AlternateProtocolServerPropertiesTest, CanonicalOverride) {
HostPortPair qux_host_port_pair("qux.c.youtube.com", 80);
AlternativeService qux_alternative_service(QUIC, "qux.c.youtube.com", 443);
- impl_.SetAlternativeService(qux_host_port_pair, qux_alternative_service, 1.0);
+ SetAlternativeService(qux_host_port_pair, qux_alternative_service, 1.0);
alternative_service_vector =
impl_.GetAlternativeServices(test_host_port_pair);
ASSERT_EQ(1u, alternative_service_vector.size());
@@ -673,8 +858,8 @@ TEST_F(AlternateProtocolServerPropertiesTest, ClearWithCanonical) {
AlternativeService canonical_alternative_service(QUIC, "bar.c.youtube.com",
1234);
- impl_.SetAlternativeService(canonical_host_port_pair,
- canonical_alternative_service, 1.0);
+ SetAlternativeService(canonical_host_port_pair, canonical_alternative_service,
+ 1.0);
impl_.Clear();
EXPECT_FALSE(HasAlternativeService(test_host_port_pair));
}
@@ -683,7 +868,7 @@ TEST_F(AlternateProtocolServerPropertiesTest,
ExpireBrokenAlternateProtocolMappings) {
HostPortPair host_port_pair("foo", 443);
AlternativeService alternative_service(QUIC, "foo", 443);
- impl_.SetAlternativeService(host_port_pair, alternative_service, 1.0);
+ SetAlternativeService(host_port_pair, alternative_service, 1.0);
EXPECT_TRUE(HasAlternativeService(host_port_pair));
EXPECT_FALSE(impl_.IsAlternativeServiceBroken(alternative_service));
EXPECT_FALSE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
@@ -700,6 +885,45 @@ TEST_F(AlternateProtocolServerPropertiesTest,
EXPECT_TRUE(impl_.WasAlternativeServiceRecentlyBroken(alternative_service));
}
+// Regression test for https://crbug.com/505413.
+TEST_F(AlternateProtocolServerPropertiesTest, RemoveExpiredBrokenAltSvc) {
+ HostPortPair foo_host_port_pair("foo", 443);
+ AlternativeService bar_alternative_service(QUIC, "bar", 443);
+ SetAlternativeService(foo_host_port_pair, bar_alternative_service, 1.0);
+ EXPECT_TRUE(HasAlternativeService(foo_host_port_pair));
+
+ HostPortPair bar_host_port_pair1("bar", 80);
+ AlternativeService nohost_alternative_service(QUIC, "", 443);
+ SetAlternativeService(bar_host_port_pair1, nohost_alternative_service, 1.0);
+ EXPECT_TRUE(HasAlternativeService(bar_host_port_pair1));
+
+ HostPortPair bar_host_port_pair2("bar", 443);
+ AlternativeService baz_alternative_service(QUIC, "baz", 1234);
+ SetAlternativeService(bar_host_port_pair2, baz_alternative_service, 1.0);
+ EXPECT_TRUE(HasAlternativeService(bar_host_port_pair2));
+
+ // Mark "bar:443" as broken.
+ base::TimeTicks past =
+ base::TimeTicks::Now() - base::TimeDelta::FromSeconds(42);
+ HttpServerPropertiesImplPeer::AddBrokenAlternativeServiceWithExpirationTime(
+ impl_, bar_alternative_service, past);
+
+ // Expire brokenness of "bar:443".
+ HttpServerPropertiesImplPeer::ExpireBrokenAlternateProtocolMappings(impl_);
+
+ // "foo:443" should have no alternative service now.
+ EXPECT_FALSE(HasAlternativeService(foo_host_port_pair));
+ // "bar:80" should have no alternative service now.
+ EXPECT_FALSE(HasAlternativeService(bar_host_port_pair1));
+ // The alternative service of "bar:443" should be unaffected.
+ EXPECT_TRUE(HasAlternativeService(bar_host_port_pair2));
+
+ EXPECT_TRUE(
+ impl_.WasAlternativeServiceRecentlyBroken(bar_alternative_service));
+ EXPECT_FALSE(
+ impl_.WasAlternativeServiceRecentlyBroken(baz_alternative_service));
+}
+
typedef HttpServerPropertiesImplTest SpdySettingsServerPropertiesTest;
TEST_F(SpdySettingsServerPropertiesTest, Initialize) {
diff --git a/chromium/net/http/http_server_properties_manager.cc b/chromium/net/http/http_server_properties_manager.cc
index d89efab5a41..2577f953cd8 100644
--- a/chromium/net/http/http_server_properties_manager.cc
+++ b/chromium/net/http/http_server_properties_manager.cc
@@ -14,6 +14,7 @@
#include "base/thread_task_runner_handle.h"
#include "base/values.h"
#include "net/base/ip_address_number.h"
+#include "net/base/port_util.h"
namespace net {
@@ -63,6 +64,7 @@ const char kProtocolKey[] = "protocol_str";
const char kHostKey[] = "host";
const char kPortKey[] = "port";
const char kProbabilityKey[] = "probability";
+const char kExpirationKey[] = "expiration";
const char kNetworkStatsKey[] = "network_stats";
const char kSrttKey[] = "srtt";
@@ -84,8 +86,7 @@ HttpServerPropertiesManager::HttpServerPropertiesManager(
pref_weak_ptr_factory_.reset(
new base::WeakPtrFactory<HttpServerPropertiesManager>(this));
pref_weak_ptr_ = pref_weak_ptr_factory_->GetWeakPtr();
- pref_cache_update_timer_.reset(
- new base::OneShotTimer<HttpServerPropertiesManager>);
+ pref_cache_update_timer_.reset(new base::OneShotTimer);
pref_change_registrar_.Init(pref_service_);
pref_change_registrar_.Add(
path_,
@@ -104,8 +105,7 @@ void HttpServerPropertiesManager::InitializeOnNetworkThread() {
new base::WeakPtrFactory<HttpServerPropertiesManager>(this));
http_server_properties_impl_.reset(new HttpServerPropertiesImpl());
- network_prefs_update_timer_.reset(
- new base::OneShotTimer<HttpServerPropertiesManager>);
+ network_prefs_update_timer_.reset(new base::OneShotTimer);
pref_task_runner_->PostTask(
FROM_HERE,
@@ -199,10 +199,11 @@ AlternativeServiceVector HttpServerPropertiesManager::GetAlternativeServices(
bool HttpServerPropertiesManager::SetAlternativeService(
const HostPortPair& origin,
const AlternativeService& alternative_service,
- double alternative_probability) {
+ double alternative_probability,
+ base::Time expiration) {
DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
const bool changed = http_server_properties_impl_->SetAlternativeService(
- origin, alternative_service, alternative_probability);
+ origin, alternative_service, alternative_probability, expiration);
if (changed) {
ScheduleUpdatePrefsOnNetworkThread(SET_ALTERNATIVE_SERVICES);
}
@@ -523,32 +524,34 @@ void HttpServerPropertiesManager::AddToSpdySettingsMap(
spdy_settings_map->Put(server, settings_map);
}
-AlternativeServiceInfo HttpServerPropertiesManager::ParseAlternativeServiceDict(
+bool HttpServerPropertiesManager::ParseAlternativeServiceDict(
const base::DictionaryValue& alternative_service_dict,
- const std::string& server_str) {
+ const std::string& server_str,
+ AlternativeServiceInfo* alternative_service_info) {
// Protocol is mandatory.
std::string protocol_str;
if (!alternative_service_dict.GetStringWithoutPathExpansion(kProtocolKey,
&protocol_str)) {
DVLOG(1) << "Malformed alternative service protocol string for server: "
<< server_str;
- return AlternativeServiceInfo();
+ return false;
}
AlternateProtocol protocol = AlternateProtocolFromString(protocol_str);
if (!IsAlternateProtocolValid(protocol)) {
DVLOG(1) << "Invalid alternative service protocol string for server: "
<< server_str;
- return AlternativeServiceInfo();
+ return false;
}
+ alternative_service_info->alternative_service.protocol = protocol;
// Host is optional, defaults to "".
- std::string host;
+ alternative_service_info->alternative_service.host.clear();
if (alternative_service_dict.HasKey(kHostKey) &&
- !alternative_service_dict.GetStringWithoutPathExpansion(kHostKey,
- &host)) {
+ !alternative_service_dict.GetStringWithoutPathExpansion(
+ kHostKey, &(alternative_service_info->alternative_service.host))) {
DVLOG(1) << "Malformed alternative service host string for server: "
<< server_str;
- return AlternativeServiceInfo();
+ return false;
}
// Port is mandatory.
@@ -556,21 +559,56 @@ AlternativeServiceInfo HttpServerPropertiesManager::ParseAlternativeServiceDict(
if (!alternative_service_dict.GetInteger(kPortKey, &port) ||
!IsPortValid(port)) {
DVLOG(1) << "Malformed alternative service port for server: " << server_str;
- return AlternativeServiceInfo();
+ return false;
}
+ alternative_service_info->alternative_service.port =
+ static_cast<uint32>(port);
// Probability is optional, defaults to 1.0.
- double probability = 1.0;
+ alternative_service_info->probability = 1.0;
if (alternative_service_dict.HasKey(kProbabilityKey) &&
- !alternative_service_dict.GetDoubleWithoutPathExpansion(kProbabilityKey,
- &probability)) {
+ !alternative_service_dict.GetDoubleWithoutPathExpansion(
+ kProbabilityKey, &(alternative_service_info->probability))) {
DVLOG(1) << "Malformed alternative service probability for server: "
<< server_str;
- return AlternativeServiceInfo();
+ return false;
}
- return AlternativeServiceInfo(protocol, host, static_cast<uint16>(port),
- probability);
+ // Expiration is optional, defaults to one day.
+ base::Time expiration;
+ if (!alternative_service_dict.HasKey(kExpirationKey)) {
+ alternative_service_info->expiration =
+ base::Time::Now() + base::TimeDelta::FromDays(1);
+ return true;
+ }
+
+ std::string expiration_string;
+ if (alternative_service_dict.GetStringWithoutPathExpansion(
+ kExpirationKey, &expiration_string)) {
+ int64 expiration_int64 = 0;
+ if (!base::StringToInt64(expiration_string, &expiration_int64)) {
+ DVLOG(1) << "Malformed alternative service expiration for server: "
+ << server_str;
+ return false;
+ }
+ alternative_service_info->expiration =
+ base::Time::FromInternalValue(expiration_int64);
+ return true;
+ }
+
+ // Early release 46 Dev and Canary versions stored expiration as double.
+ // TODO(bnc) Remove the following code parsing double around 2015-10-01.
+ double expiration_double;
+ if (alternative_service_dict.GetDoubleWithoutPathExpansion(
+ kExpirationKey, &expiration_double)) {
+ alternative_service_info->expiration =
+ base::Time::FromDoubleT(expiration_double);
+ return true;
+ }
+
+ DVLOG(1) << "Malformed alternative service expiration for server: "
+ << server_str;
+ return false;
}
bool HttpServerPropertiesManager::AddToAlternativeServiceMap(
@@ -590,11 +628,10 @@ bool HttpServerPropertiesManager::AddToAlternativeServiceMap(
if (!alternative_service_list_item->GetAsDictionary(
&alternative_service_dict))
return false;
- AlternativeServiceInfo alternative_service_info =
- ParseAlternativeServiceDict(*alternative_service_dict,
- server.ToString());
- if (alternative_service_info.alternative_service.protocol ==
- UNINITIALIZED_ALTERNATE_PROTOCOL) {
+ AlternativeServiceInfo alternative_service_info;
+ if (!ParseAlternativeServiceDict(*alternative_service_dict,
+ server.ToString(),
+ &alternative_service_info)) {
return false;
}
alternative_service_info_vector.push_back(alternative_service_info);
@@ -607,11 +644,10 @@ bool HttpServerPropertiesManager::AddToAlternativeServiceMap(
kAlternateProtocolKey, &alternative_service_dict)) {
return true;
}
- AlternativeServiceInfo alternative_service_info =
- ParseAlternativeServiceDict(*alternative_service_dict,
- server.ToString());
- if (alternative_service_info.alternative_service.protocol ==
- UNINITIALIZED_ALTERNATE_PROTOCOL) {
+ AlternativeServiceInfo alternative_service_info;
+ if (!ParseAlternativeServiceDict(*alternative_service_dict,
+ server.ToString(),
+ &alternative_service_info)) {
return false;
}
alternative_service_info_vector.push_back(alternative_service_info);
@@ -981,6 +1017,11 @@ void HttpServerPropertiesManager::SaveAlternativeServiceToServerPrefs(
kProtocolKey, AlternateProtocolToString(alternative_service.protocol));
alternative_service_dict->SetDouble(kProbabilityKey,
alternative_service_info.probability);
+ // JSON cannot store int64, so expiration is converted to a string.
+ alternative_service_dict->SetString(
+ kExpirationKey,
+ base::Int64ToString(
+ alternative_service_info.expiration.ToInternalValue()));
alternative_service_list->Append(alternative_service_dict);
}
if (alternative_service_list->GetSize() == 0)
diff --git a/chromium/net/http/http_server_properties_manager.h b/chromium/net/http/http_server_properties_manager.h
index 3b8f155d6e4..1e09ff7a75d 100644
--- a/chromium/net/http/http_server_properties_manager.h
+++ b/chromium/net/http/http_server_properties_manager.h
@@ -10,6 +10,7 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/prefs/pref_change_registrar.h"
@@ -91,7 +92,8 @@ class NET_EXPORT HttpServerPropertiesManager : public HttpServerProperties {
const HostPortPair& origin) override;
bool SetAlternativeService(const HostPortPair& origin,
const AlternativeService& alternative_service,
- double alternative_probability) override;
+ double alternative_probability,
+ base::Time expiration) override;
bool SetAlternativeServices(const HostPortPair& origin,
const AlternativeServiceInfoVector&
alternative_service_info_vector) override;
@@ -205,6 +207,10 @@ class NET_EXPORT HttpServerPropertiesManager : public HttpServerProperties {
const base::Closure& completion);
private:
+ FRIEND_TEST_ALL_PREFIXES(HttpServerPropertiesManagerTest,
+ AddToAlternativeServiceMap);
+ FRIEND_TEST_ALL_PREFIXES(HttpServerPropertiesManagerTest,
+ AlternativeServiceExpirationDouble);
void OnHttpServerPropertiesChanged();
bool ReadSupportsQuic(const base::DictionaryValue& server_dict,
@@ -212,9 +218,10 @@ class NET_EXPORT HttpServerPropertiesManager : public HttpServerProperties {
void AddToSpdySettingsMap(const HostPortPair& server,
const base::DictionaryValue& server_dict,
SpdySettingsMap* spdy_settings_map);
- AlternativeServiceInfo ParseAlternativeServiceDict(
+ bool ParseAlternativeServiceDict(
const base::DictionaryValue& alternative_service_dict,
- const std::string& server_str);
+ const std::string& server_str,
+ AlternativeServiceInfo* alternative_service_info);
bool AddToAlternativeServiceMap(
const HostPortPair& server,
const base::DictionaryValue& server_dict,
@@ -245,8 +252,7 @@ class NET_EXPORT HttpServerPropertiesManager : public HttpServerProperties {
base::WeakPtr<HttpServerPropertiesManager> pref_weak_ptr_;
// Used to post cache update tasks.
- scoped_ptr<base::OneShotTimer<HttpServerPropertiesManager> >
- pref_cache_update_timer_;
+ scoped_ptr<base::OneShotTimer> pref_cache_update_timer_;
// Used to track the spdy servers changes.
PrefChangeRegistrar pref_change_registrar_;
@@ -261,8 +267,7 @@ class NET_EXPORT HttpServerPropertiesManager : public HttpServerProperties {
const scoped_refptr<base::SequencedTaskRunner> network_task_runner_;
// Used to post |prefs::kHttpServerProperties| pref update tasks.
- scoped_ptr<base::OneShotTimer<HttpServerPropertiesManager> >
- network_prefs_update_timer_;
+ scoped_ptr<base::OneShotTimer> network_prefs_update_timer_;
scoped_ptr<HttpServerPropertiesImpl> http_server_properties_impl_;
diff --git a/chromium/net/http/http_server_properties_manager_unittest.cc b/chromium/net/http/http_server_properties_manager_unittest.cc
index 2a5d0497e2a..2164bb52485 100644
--- a/chromium/net/http/http_server_properties_manager_unittest.cc
+++ b/chromium/net/http/http_server_properties_manager_unittest.cc
@@ -5,6 +5,7 @@
#include "net/http/http_server_properties_manager.h"
#include "base/basictypes.h"
+#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/message_loop/message_loop.h"
#include "base/prefs/pref_registry_simple.h"
@@ -100,11 +101,14 @@ class TestingHttpServerPropertiesManager : public HttpServerPropertiesManager {
DISALLOW_COPY_AND_ASSIGN(TestingHttpServerPropertiesManager);
};
+} // namespace
+
class HttpServerPropertiesManagerTest : public testing::Test {
protected:
HttpServerPropertiesManagerTest() {}
void SetUp() override {
+ one_day_from_now_ = base::Time::Now() + base::TimeDelta::FromDays(1);
pref_service_.registry()->RegisterDictionaryPref(kTestHttpServerProperties);
http_server_props_manager_.reset(
new StrictMock<TestingHttpServerPropertiesManager>(
@@ -170,6 +174,7 @@ class HttpServerPropertiesManagerTest : public testing::Test {
//base::RunLoop loop_;
TestingPrefServiceSimple pref_service_;
scoped_ptr<TestingHttpServerPropertiesManager> http_server_props_manager_;
+ base::Time one_day_from_now_;
private:
DISALLOW_COPY_AND_ASSIGN(HttpServerPropertiesManagerTest);
@@ -192,7 +197,7 @@ TEST_F(HttpServerPropertiesManagerTest,
// Set up alternative_services for www.google.com:80.
base::DictionaryValue* alternative_service_dict0 = new base::DictionaryValue;
alternative_service_dict0->SetInteger("port", 443);
- alternative_service_dict0->SetString("protocol_str", "npn-spdy/3");
+ alternative_service_dict0->SetString("protocol_str", "npn-h2");
base::DictionaryValue* alternative_service_dict1 = new base::DictionaryValue;
alternative_service_dict1->SetInteger("port", 1234);
alternative_service_dict1->SetString("protocol_str", "quic");
@@ -268,7 +273,7 @@ TEST_F(HttpServerPropertiesManagerTest,
AlternativeServiceMap::const_iterator map_it = map.begin();
EXPECT_EQ("www.google.com", map_it->first.host());
ASSERT_EQ(2u, map_it->second.size());
- EXPECT_EQ(NPN_SPDY_3, map_it->second[0].alternative_service.protocol);
+ EXPECT_EQ(NPN_HTTP_2, map_it->second[0].alternative_service.protocol);
EXPECT_TRUE(map_it->second[0].alternative_service.host.empty());
EXPECT_EQ(443, map_it->second[0].alternative_service.port);
EXPECT_EQ(QUIC, map_it->second[1].alternative_service.protocol);
@@ -308,7 +313,7 @@ TEST_F(HttpServerPropertiesManagerTest, BadCachedHostPortPair) {
// Set up alternative_service for www.google.com:65536.
base::DictionaryValue* alternative_service_dict = new base::DictionaryValue;
- alternative_service_dict->SetString("protocol_str", "npn-spdy/3");
+ alternative_service_dict->SetString("protocol_str", "npn-h2");
alternative_service_dict->SetInteger("port", 80);
base::ListValue* alternative_service_list = new base::ListValue;
alternative_service_list->Append(alternative_service_dict);
@@ -361,7 +366,7 @@ TEST_F(HttpServerPropertiesManagerTest, BadCachedAltProtocolPort) {
// Set up alternative_service for www.google.com:80.
base::DictionaryValue* alternative_service_dict = new base::DictionaryValue;
- alternative_service_dict->SetString("protocol_str", "npn-spdy/3");
+ alternative_service_dict->SetString("protocol_str", "npn-h2");
alternative_service_dict->SetInteger("port", 65536);
base::ListValue* alternative_service_list = new base::ListValue;
alternative_service_list->Append(alternative_service_dict);
@@ -524,11 +529,11 @@ TEST_F(HttpServerPropertiesManagerTest, GetAlternativeServices) {
EXPECT_FALSE(HasAlternativeService(spdy_server_mail));
const AlternativeService alternative_service(NPN_HTTP_2, "mail.google.com",
443);
- http_server_props_manager_->SetAlternativeService(spdy_server_mail,
- alternative_service, 1.0);
+ http_server_props_manager_->SetAlternativeService(
+ spdy_server_mail, alternative_service, 1.0, one_day_from_now_);
// ExpectScheduleUpdatePrefsOnNetworkThread() should be called only once.
- http_server_props_manager_->SetAlternativeService(spdy_server_mail,
- alternative_service, 1.0);
+ http_server_props_manager_->SetAlternativeService(
+ spdy_server_mail, alternative_service, 1.0, one_day_from_now_);
// Run the task.
base::RunLoop().RunUntilIdle();
@@ -550,10 +555,10 @@ TEST_F(HttpServerPropertiesManagerTest, SetAlternativeServices) {
const AlternativeService alternative_service1(NPN_HTTP_2, "mail.google.com",
443);
alternative_service_info_vector.push_back(
- AlternativeServiceInfo(alternative_service1, 1.0));
+ AlternativeServiceInfo(alternative_service1, 1.0, one_day_from_now_));
const AlternativeService alternative_service2(QUIC, "mail.google.com", 1234);
alternative_service_info_vector.push_back(
- AlternativeServiceInfo(alternative_service2, 1.0));
+ AlternativeServiceInfo(alternative_service2, 1.0, one_day_from_now_));
http_server_props_manager_->SetAlternativeServices(
spdy_server_mail, alternative_service_info_vector);
// ExpectScheduleUpdatePrefsOnNetworkThread() should be called only once.
@@ -594,8 +599,8 @@ TEST_F(HttpServerPropertiesManagerTest, ClearAlternativeServices) {
HostPortPair spdy_server_mail("mail.google.com", 80);
EXPECT_FALSE(HasAlternativeService(spdy_server_mail));
AlternativeService alternative_service(NPN_HTTP_2, "mail.google.com", 443);
- http_server_props_manager_->SetAlternativeService(spdy_server_mail,
- alternative_service, 1.0);
+ http_server_props_manager_->SetAlternativeService(
+ spdy_server_mail, alternative_service, 1.0, one_day_from_now_);
ExpectScheduleUpdatePrefsOnNetworkThread();
http_server_props_manager_->ClearAlternativeServices(spdy_server_mail);
// ExpectScheduleUpdatePrefsOnNetworkThread() should be called only once.
@@ -616,8 +621,8 @@ TEST_F(HttpServerPropertiesManagerTest, ConfirmAlternativeService) {
AlternativeService alternative_service(NPN_HTTP_2, "mail.google.com", 443);
ExpectScheduleUpdatePrefsOnNetworkThread();
- http_server_props_manager_->SetAlternativeService(spdy_server_mail,
- alternative_service, 1.0);
+ http_server_props_manager_->SetAlternativeService(
+ spdy_server_mail, alternative_service, 1.0, one_day_from_now_);
EXPECT_FALSE(http_server_props_manager_->IsAlternativeServiceBroken(
alternative_service));
@@ -704,9 +709,9 @@ TEST_F(HttpServerPropertiesManagerTest, Clear) {
HostPortPair spdy_server_mail("mail.google.com", 443);
http_server_props_manager_->SetSupportsSpdy(spdy_server_mail, true);
- AlternativeService alternative_service(NPN_HTTP_2, "mail.google.com", 443);
- http_server_props_manager_->SetAlternativeService(spdy_server_mail,
- alternative_service, 1.0);
+ AlternativeService alternative_service(NPN_HTTP_2, "mail.google.com", 1234);
+ http_server_props_manager_->SetAlternativeService(
+ spdy_server_mail, alternative_service, 1.0, one_day_from_now_);
IPAddressNumber actual_address;
CHECK(ParseIPLiteralToNumber("127.0.0.1", &actual_address));
http_server_props_manager_->SetSupportsQuic(true, actual_address);
@@ -776,7 +781,7 @@ TEST_F(HttpServerPropertiesManagerTest, BadSupportsQuic) {
for (int i = 0; i < 200; ++i) {
// Set up alternative_service for www.google.com:i.
base::DictionaryValue* alternative_service_dict = new base::DictionaryValue;
- alternative_service_dict->SetString("protocol_str", "npn-h2");
+ alternative_service_dict->SetString("protocol_str", "quic");
alternative_service_dict->SetInteger("port", i);
base::ListValue* alternative_service_list = new base::ListValue;
alternative_service_list->Append(alternative_service_dict);
@@ -820,7 +825,7 @@ TEST_F(HttpServerPropertiesManagerTest, BadSupportsQuic) {
http_server_props_manager_->GetAlternativeServices(
HostPortPair::FromString(server));
ASSERT_EQ(1u, alternative_service_vector.size());
- EXPECT_EQ(NPN_HTTP_2, alternative_service_vector[0].protocol);
+ EXPECT_EQ(QUIC, alternative_service_vector[0].protocol);
EXPECT_EQ(i, alternative_service_vector[0].port);
}
@@ -839,19 +844,24 @@ TEST_F(HttpServerPropertiesManagerTest, UpdateCacheWithPrefs) {
// Set alternate protocol.
AlternativeServiceInfoVector alternative_service_info_vector;
AlternativeService www_alternative_service1(NPN_HTTP_2, "", 443);
+ base::Time expiration1;
+ ASSERT_TRUE(base::Time::FromUTCString("2036-12-01 10:00:00", &expiration1));
alternative_service_info_vector.push_back(
- AlternativeServiceInfo(www_alternative_service1, 1.0));
+ AlternativeServiceInfo(www_alternative_service1, 1.0, expiration1));
AlternativeService www_alternative_service2(NPN_HTTP_2, "www.google.com",
1234);
+ base::Time expiration2;
+ ASSERT_TRUE(base::Time::FromUTCString("2036-12-31 10:00:00", &expiration2));
alternative_service_info_vector.push_back(
- AlternativeServiceInfo(www_alternative_service2, 0.7));
+ AlternativeServiceInfo(www_alternative_service2, 0.7, expiration2));
http_server_props_manager_->SetAlternativeServices(
server_www, alternative_service_info_vector);
AlternativeService mail_alternative_service(NPN_SPDY_3_1, "foo.google.com",
444);
+ base::Time expiration3 = base::Time::Max();
http_server_props_manager_->SetAlternativeService(
- server_mail, mail_alternative_service, 0.2);
+ server_mail, mail_alternative_service, 0.2, expiration3);
// Set ServerNetworkStats.
ServerNetworkStats stats;
@@ -872,13 +882,15 @@ TEST_F(HttpServerPropertiesManagerTest, UpdateCacheWithPrefs) {
// Verify preferences.
const char expected_json[] =
"{\"servers\":{\"mail.google.com:80\":{\"alternative_service\":[{"
- "\"host\":\"foo.google.com\",\"port\":444,\"probability\":0.2,"
- "\"protocol_str\":\"npn-spdy/3.1\"}],\"network_stats\":{\"srtt\":42}},"
- "\"www.google.com:80\":{\"alternative_service\":[{\"port\":443,"
- "\"probability\":1.0,\"protocol_str\":\"npn-h2\"},"
- "{\"host\":\"www.google.com\",\"port\":1234,\"probability\":0.7,"
- "\"protocol_str\":\"npn-h2\"}]}},\"supports_quic\":"
- "{\"address\":\"127.0.0.1\",\"used_quic\":true},\"version\":3}";
+ "\"expiration\":\"9223372036854775807\",\"host\":\"foo.google.com\","
+ "\"port\":444,\"probability\":0.2,\"protocol_str\":\"npn-spdy/3.1\"}],"
+ "\"network_stats\":{\"srtt\":42}},\"www.google.com:80\":{"
+ "\"alternative_service\":[{\"expiration\":\"13756212000000000\","
+ "\"port\":443,\"probability\":1.0,\"protocol_str\":\"npn-h2\"},"
+ "{\"expiration\":\"13758804000000000\",\"host\":\"www.google.com\","
+ "\"port\":1234,\"probability\":0.7,\"protocol_str\":\"npn-h2\"}]}},"
+ "\"supports_quic\":{\"address\":\"127.0.0.1\",\"used_quic\":true},"
+ "\"version\":3}";
const base::Value* http_server_properties =
pref_service_.GetUserPref(kTestHttpServerProperties);
@@ -889,6 +901,95 @@ TEST_F(HttpServerPropertiesManagerTest, UpdateCacheWithPrefs) {
EXPECT_EQ(expected_json, preferences_json);
}
+TEST_F(HttpServerPropertiesManagerTest, AddToAlternativeServiceMap) {
+ scoped_ptr<base::Value> server_value = base::JSONReader::Read(
+ "{\"alternative_service\":[{\"port\":443,\"protocol_str\":\"npn-h2\"},"
+ "{\"port\":123,\"protocol_str\":\"quic\",\"probability\":0.7,"
+ "\"expiration\":\"9223372036854775807\"},{\"host\":\"example.org\","
+ "\"port\":1234,\"protocol_str\":\"npn-h2\",\"probability\":0.2,"
+ "\"expiration\":\"13758804000000000\"}]}");
+ ASSERT_TRUE(server_value);
+ base::DictionaryValue* server_dict;
+ ASSERT_TRUE(server_value->GetAsDictionary(&server_dict));
+
+ const HostPortPair host_port_pair("example.com", 443);
+ AlternativeServiceMap alternative_service_map(/*max_size=*/5);
+ EXPECT_TRUE(http_server_props_manager_->AddToAlternativeServiceMap(
+ host_port_pair, *server_dict, &alternative_service_map));
+
+ AlternativeServiceMap::iterator it =
+ alternative_service_map.Get(host_port_pair);
+ ASSERT_NE(alternative_service_map.end(), it);
+ AlternativeServiceInfoVector alternative_service_info_vector = it->second;
+ ASSERT_EQ(3u, alternative_service_info_vector.size());
+
+ EXPECT_EQ(NPN_HTTP_2,
+ alternative_service_info_vector[0].alternative_service.protocol);
+ EXPECT_EQ("", alternative_service_info_vector[0].alternative_service.host);
+ EXPECT_EQ(443, alternative_service_info_vector[0].alternative_service.port);
+ // Probability defaults to 1.0.
+ EXPECT_DOUBLE_EQ(1.0, alternative_service_info_vector[0].probability);
+ // Expiration defaults to one day from now, testing with tolerance.
+ const base::Time now = base::Time::Now();
+ const base::Time expiration = alternative_service_info_vector[0].expiration;
+ EXPECT_LE(now + base::TimeDelta::FromHours(23), expiration);
+ EXPECT_GE(now + base::TimeDelta::FromDays(1), expiration);
+
+ EXPECT_EQ(QUIC,
+ alternative_service_info_vector[1].alternative_service.protocol);
+ EXPECT_EQ("", alternative_service_info_vector[1].alternative_service.host);
+ EXPECT_EQ(123, alternative_service_info_vector[1].alternative_service.port);
+ EXPECT_DOUBLE_EQ(0.7, alternative_service_info_vector[1].probability);
+ // numeric_limits<int64>::max() represents base::Time::Max().
+ EXPECT_EQ(base::Time::Max(), alternative_service_info_vector[1].expiration);
+
+ EXPECT_EQ(NPN_HTTP_2,
+ alternative_service_info_vector[2].alternative_service.protocol);
+ EXPECT_EQ("example.org",
+ alternative_service_info_vector[2].alternative_service.host);
+ EXPECT_EQ(1234, alternative_service_info_vector[2].alternative_service.port);
+ EXPECT_DOUBLE_EQ(0.2, alternative_service_info_vector[2].probability);
+ base::Time expected_expiration;
+ ASSERT_TRUE(
+ base::Time::FromUTCString("2036-12-31 10:00:00", &expected_expiration));
+ EXPECT_EQ(expected_expiration, alternative_service_info_vector[2].expiration);
+}
+
+// Early release 46 Dev and Canary builds serialized alternative service
+// expiration as double. Test that they are properly parsed.
+// TODO(bnc) Remove this test around 2015-10-01,
+// and remove corresponding FRIEND macro from header file.
+TEST_F(HttpServerPropertiesManagerTest, AlternativeServiceExpirationDouble) {
+ scoped_ptr<base::Value> server_value = base::JSONReader::Read(
+ "{\"alternative_service\":[{\"port\":443,\"protocol_str\":\"npn-h2\","
+ "\"expiration\":1234567890.0}]}");
+ ASSERT_TRUE(server_value);
+ base::DictionaryValue* server_dict;
+ ASSERT_TRUE(server_value->GetAsDictionary(&server_dict));
+
+ const HostPortPair host_port_pair("example.com", 443);
+ AlternativeServiceMap alternative_service_map(/*max_size=*/5);
+ EXPECT_TRUE(http_server_props_manager_->AddToAlternativeServiceMap(
+ host_port_pair, *server_dict, &alternative_service_map));
+
+ AlternativeServiceMap::iterator it =
+ alternative_service_map.Get(host_port_pair);
+ ASSERT_NE(alternative_service_map.end(), it);
+ AlternativeServiceInfoVector alternative_service_info_vector = it->second;
+ ASSERT_EQ(1u, alternative_service_info_vector.size());
+
+ EXPECT_EQ(NPN_HTTP_2,
+ alternative_service_info_vector[0].alternative_service.protocol);
+ EXPECT_EQ("", alternative_service_info_vector[0].alternative_service.host);
+ EXPECT_EQ(443, alternative_service_info_vector[0].alternative_service.port);
+ // Probability defaults to 1.0.
+ EXPECT_DOUBLE_EQ(1.0, alternative_service_info_vector[0].probability);
+ base::Time expected_expiration;
+ ASSERT_TRUE(
+ base::Time::FromUTCString("2009-02-13 23:31:30", &expected_expiration));
+ EXPECT_EQ(expected_expiration, alternative_service_info_vector[0].expiration);
+}
+
TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache0) {
// Post an update task to the UI thread.
http_server_props_manager_->ScheduleUpdateCacheOnPrefThread();
@@ -961,6 +1062,4 @@ TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs2) {
base::RunLoop().RunUntilIdle();
}
-} // namespace
-
} // namespace net
diff --git a/chromium/net/http/http_status_line_validator.cc b/chromium/net/http/http_status_line_validator.cc
new file mode 100644
index 00000000000..5b8284cb5a3
--- /dev/null
+++ b/chromium/net/http/http_status_line_validator.cc
@@ -0,0 +1,136 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/http/http_status_line_validator.h"
+
+#include <vector>
+
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+
+namespace net {
+
+using base::StringPiece;
+
+HttpStatusLineValidator::StatusLineStatus
+HttpStatusLineValidator::ValidateStatusLine(const StringPiece& status_line) {
+ std::vector<StringPiece> fields = base::SplitStringPiece(
+ status_line, " ", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+ // Permissively split fields, meaning:
+ // 1) Extra whitespace separating fields ignored
+ // 2) Extra leading/trailing whitespace removed
+ std::vector<StringPiece> loose_fields = base::SplitStringPiece(
+ status_line, " ", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
+
+ // Fields: HTTP-version status-code reason-phrase
+ if (fields.empty() || loose_fields.empty())
+ return STATUS_LINE_EMPTY;
+
+ StatusLineStatus rv = CheckHttpVersionSyntax(fields[0]);
+ if (rv != STATUS_LINE_OK)
+ return rv;
+
+ if (fields.size() < 2)
+ return STATUS_LINE_MISSING_STATUS_CODE;
+
+ rv = CheckStatusCodeSyntax(fields[1]);
+ if (rv != STATUS_LINE_OK)
+ return rv;
+
+ // At this point the field splitting could be wrong, so check for extra
+ // whitespace/padding on the result code.
+ // Note that there is no such thing as "extra whitespace" on the
+ // reason-phrase, since spaces are legal inside it.
+ if (loose_fields[1] != fields[1])
+ return STATUS_LINE_EXCESS_WHITESPACE;
+
+ // An empty reason phrase will cause there to be only two fields in |fields|
+ // but more than that in |loose_fields|.
+ if (loose_fields.size() < 3)
+ return STATUS_LINE_MISSING_REASON_PHRASE;
+ return CheckReasonPhraseSyntax(fields, 2);
+}
+
+HttpStatusLineValidator::StatusLineStatus
+HttpStatusLineValidator::CheckHttpVersionSyntax(const StringPiece& version) {
+ static const char kProtoName[] = "HTTP";
+ static const char kDigits[] = "0123456789";
+ if (!base::StartsWith(version, kProtoName,
+ base::CompareCase::INSENSITIVE_ASCII)) {
+ return STATUS_LINE_NOT_HTTP;
+ }
+ if (!base::StartsWith(version, kProtoName, base::CompareCase::SENSITIVE))
+ return STATUS_LINE_HTTP_CASE_MISMATCH;
+ // Okay, definitely "HTTP" at the start. Now check for the separating slash
+ // and version number components:
+ size_t slash = version.find('/');
+ if (slash != strlen(kProtoName))
+ return STATUS_LINE_HTTP_NO_VERSION;
+ StringPiece rest = version.substr(slash + 1);
+ size_t sep = rest.find('.');
+ if (sep == StringPiece::npos) {
+ return STATUS_LINE_INVALID_VERSION;
+ }
+ StringPiece major = rest.substr(0, sep);
+ if (major.length() == 0)
+ return STATUS_LINE_INVALID_VERSION;
+ StringPiece minor = rest.substr(sep + 1);
+ if (minor.length() == 0)
+ return STATUS_LINE_INVALID_VERSION;
+ if (major.find_first_not_of(kDigits) != major.npos ||
+ minor.find_first_not_of(kDigits) != minor.npos) {
+ return STATUS_LINE_INVALID_VERSION;
+ }
+
+ if (major.length() != 1 || minor.length() != 1)
+ return STATUS_LINE_MULTI_DIGIT_VERSION;
+
+ // It is now known that version looks like:
+ // HTTP/x.y
+ // For single digits x and y.
+ // Check that x == '1' and y == '0' or '1'
+ if (major[0] != '1' || (minor[0] != '0' && minor[0] != '1')) {
+ if (major[0] == '0' && minor[0] == '9')
+ return STATUS_LINE_EXPLICIT_0_9;
+ else
+ return STATUS_LINE_UNKNOWN_VERSION;
+ }
+ return STATUS_LINE_OK;
+}
+
+HttpStatusLineValidator::StatusLineStatus
+HttpStatusLineValidator::CheckStatusCodeSyntax(const StringPiece& status_code) {
+ if (status_code.length() < 3)
+ return STATUS_LINE_INVALID_STATUS_CODE;
+ if (!isdigit(status_code[0]) || !isdigit(status_code[1]) ||
+ !isdigit(status_code[2])) {
+ return STATUS_LINE_INVALID_STATUS_CODE;
+ }
+ if (status_code.length() > 3)
+ return STATUS_LINE_STATUS_CODE_TRAILING;
+ // The only valid codes are 1xx through 5xx, see RFC 7231 S6
+ if (status_code[0] < '1' || status_code[0] > '5')
+ return STATUS_LINE_RESERVED_STATUS_CODE;
+ return STATUS_LINE_OK;
+}
+
+HttpStatusLineValidator::StatusLineStatus
+HttpStatusLineValidator::CheckReasonPhraseSyntax(
+ const std::vector<StringPiece>& fields,
+ size_t start_index) {
+ for (size_t i = start_index; i < fields.size(); ++i) {
+ for (size_t j = 0; j < fields[i].length(); ++j) {
+ // VCHAR is any "visible" ASCII character, meaning any non-control
+ // character, so >= ' ' but not DEL (\x7f).
+ // obs-text is any character between \x80 and \xff.
+ // HTAB is \t, SP is ' '
+ char c = fields[i][j];
+ if (c == '\x7f' || (c < ' ' && c != '\t'))
+ return STATUS_LINE_REASON_DISALLOWED_CHARACTER;
+ }
+ }
+ return STATUS_LINE_OK;
+}
+
+} // namespace net
diff --git a/chromium/net/http/http_status_line_validator.h b/chromium/net/http/http_status_line_validator.h
new file mode 100644
index 00000000000..1bfa69f878d
--- /dev/null
+++ b/chromium/net/http/http_status_line_validator.h
@@ -0,0 +1,86 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_HTTP_HTTP_STATUS_LINE_VALIDATOR_H_
+#define NET_HTTP_HTTP_STATUS_LINE_VALIDATOR_H_
+
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/strings/string_piece.h"
+#include "net/base/net_export.h"
+
+namespace net {
+
+class HttpStatusLineValidator {
+ public:
+ // RFC 7230 S3.1.2:
+ // status-line = HTTP-version SP status-code SP reason-phrase CRLF
+ // status-code = 3DIGIT
+ // reason-phrase = *( HTAB / SP / VCHAR / obs-text )
+ // And from RFC 7230 S2.6:
+ // HTTP-version = HTTP-name "/" DIGIT "." DIGIT
+ // HTTP-name = "\x48\x54\x54\x50" ; ie, "HTTP" in uppercase
+ enum StatusLineStatus {
+ // No violations found.
+ STATUS_LINE_OK = 0,
+ // ""
+ STATUS_LINE_EMPTY = 1,
+ // "xyzzy"
+ STATUS_LINE_NOT_HTTP = 2,
+ // "HtTp/1.1 ..."
+ STATUS_LINE_HTTP_CASE_MISMATCH = 3,
+ // "HTTP" or "HTTP/"
+ STATUS_LINE_HTTP_NO_VERSION = 4,
+ // "HTTP/abc" or "HTTP/1" or "HTTP/1."
+ STATUS_LINE_INVALID_VERSION = 5,
+ // "HTTP/1.234 ..."
+ STATUS_LINE_MULTI_DIGIT_VERSION = 6,
+ // "HTTP/3.0 ..."
+ STATUS_LINE_UNKNOWN_VERSION = 7,
+ // "HTTP/0.9 ..."
+ STATUS_LINE_EXPLICIT_0_9 = 8,
+ // "HTTP/1.1"
+ STATUS_LINE_MISSING_STATUS_CODE = 9,
+ // "HTTP/1.1 abc"
+ STATUS_LINE_INVALID_STATUS_CODE = 10,
+ // "HTTP/1.1 123a"
+ STATUS_LINE_STATUS_CODE_TRAILING = 11,
+ // "HTTP/1.1 404", note that "HTTP/1.1 404 " is a valid empty reason phrase
+ STATUS_LINE_MISSING_REASON_PHRASE = 12,
+ // "HTTP/1.1 200 \x01"
+ STATUS_LINE_REASON_DISALLOWED_CHARACTER = 13,
+ // "HTTP/1.1 200 OK"
+ STATUS_LINE_EXCESS_WHITESPACE = 14,
+ // "HTTP/1.1 600 OK"
+ STATUS_LINE_RESERVED_STATUS_CODE = 15,
+
+ STATUS_LINE_MAX
+ };
+
+ // Checks for violations of the RFC 7230 S3.1.2 status-line grammar, and
+ // returns the first violation found, or STATUS_LINE_OK if the status line
+ // looks conforming.
+ static StatusLineStatus NET_EXPORT_PRIVATE ValidateStatusLine(
+ const base::StringPiece& status_line);
+
+ private:
+ static StatusLineStatus CheckHttpVersionSyntax(
+ const base::StringPiece& version);
+ static StatusLineStatus CheckStatusCodeSyntax(
+ const base::StringPiece& status_code);
+ // Checks |fields| against the reason-phrase syntax in RFC 7230 S3.1.2, ie:
+ // reason-phrase = *( HTAB / SP / VCHAR / obs-text )
+ // Note that the HTTP stream parser ignores the reason-phrase entirely, so
+ // this check is needlessly pedantic.
+ static StatusLineStatus CheckReasonPhraseSyntax(
+ const std::vector<base::StringPiece>& fields,
+ size_t start_index);
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(HttpStatusLineValidator);
+};
+
+} // namespace net
+
+#endif // NET_HTTP_HTTP_STATUS_LINE_VALIDATOR_H_
diff --git a/chromium/net/http/http_status_line_validator_unittest.cc b/chromium/net/http/http_status_line_validator_unittest.cc
new file mode 100644
index 00000000000..43a8bf2360f
--- /dev/null
+++ b/chromium/net/http/http_status_line_validator_unittest.cc
@@ -0,0 +1,88 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/http/http_status_line_validator.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace {
+
+using Status = HttpStatusLineValidator::StatusLineStatus;
+
+struct ValidatorTestData {
+ const char* name;
+ const char* status_line;
+ const Status expected_status;
+};
+
+class ValidatorTest : public ::testing::Test,
+ public ::testing::WithParamInterface<ValidatorTestData> {
+ public:
+ ValidatorTest() {}
+ ~ValidatorTest() override {}
+};
+
+std::string TestName(testing::TestParamInfo<ValidatorTestData> info) {
+ return info.param.name;
+}
+
+TEST_P(ValidatorTest, Validate) {
+ const ValidatorTestData test = GetParam();
+
+ EXPECT_EQ(HttpStatusLineValidator::ValidateStatusLine(test.status_line),
+ test.expected_status);
+}
+
+const ValidatorTestData validator_tests[] = {
+ {"Http10_Ok", "HTTP/1.0 200 OK", Status::STATUS_LINE_OK},
+ {"Http11_Ok", "HTTP/1.1 200 OK", Status::STATUS_LINE_OK},
+ {"Empty", "", Status::STATUS_LINE_EMPTY},
+ {"NotHttp", "xyzzy", Status::STATUS_LINE_NOT_HTTP},
+ {"CaseMismatch", "HtTp/1.1 200 OK", Status::STATUS_LINE_HTTP_CASE_MISMATCH},
+ {"NoVersion", "HTTP 200 OK", Status::STATUS_LINE_HTTP_NO_VERSION},
+ {"InvalidVersion_0", "HTTP/a.b 200 OK",
+ Status::STATUS_LINE_INVALID_VERSION},
+ {"InvalidVersion_1", "HTTP/1.a 200 OK",
+ Status::STATUS_LINE_INVALID_VERSION},
+ {"InvalidVersion_2", "HTTP/a.1 200 OK",
+ Status::STATUS_LINE_INVALID_VERSION},
+ {"InvalidVersion_3", "HTTP/1 200 OK", Status::STATUS_LINE_INVALID_VERSION},
+ {"InvalidVersion_4", "HTTP/1. 200 OK", Status::STATUS_LINE_INVALID_VERSION},
+ {"MultiDigit_0", "HTTP/10.0 200 OK",
+ Status::STATUS_LINE_MULTI_DIGIT_VERSION},
+ {"MultiDigit_1", "HTTP/1.00 200 OK",
+ Status::STATUS_LINE_MULTI_DIGIT_VERSION},
+ {"UnknownVersion_0", "HTTP/1.2 200 OK",
+ Status::STATUS_LINE_UNKNOWN_VERSION},
+ {"UnknownVersion_1", "HTTP/2.0 200 OK",
+ Status::STATUS_LINE_UNKNOWN_VERSION},
+ {"Explicit09", "HTTP/0.9 200 OK", Status::STATUS_LINE_EXPLICIT_0_9},
+ {"MissingStatusCode", "HTTP/1.0", Status::STATUS_LINE_MISSING_STATUS_CODE},
+ {"InvalidStatusCode_0", "HTTP/1.0 abc OK",
+ Status::STATUS_LINE_INVALID_STATUS_CODE},
+ {"InvalidStatusCode_1", "HTTP/1.0 17 OK",
+ Status::STATUS_LINE_INVALID_STATUS_CODE},
+ {"StatusCodeTrailing", "HTTP/1.0 200a OK",
+ Status::STATUS_LINE_STATUS_CODE_TRAILING},
+ {"MissingReasonPhrase", "HTTP/1.0 200",
+ Status::STATUS_LINE_MISSING_REASON_PHRASE},
+ {"EmptyReasonPhrase_Ok", "HTTP/1.0 200 ", Status::STATUS_LINE_OK},
+ {"ReasonDisallowedCharacter", "HTTP/1.0 200 OK\x01",
+ Status::STATUS_LINE_REASON_DISALLOWED_CHARACTER},
+ {"ExcessWhitespace", "HTTP/1.0 200 OK",
+ Status::STATUS_LINE_EXCESS_WHITESPACE},
+ {"ReasonWhitespace_Ok", "HTTP/1.0 200 OK", Status::STATUS_LINE_OK},
+ {"ReservedStatusCode_0", "HTTP/1.0 099 OK",
+ Status::STATUS_LINE_RESERVED_STATUS_CODE},
+ {"ReservedStatusCode_1", "HTTP/1.0 600 OK",
+ Status::STATUS_LINE_RESERVED_STATUS_CODE}};
+
+INSTANTIATE_TEST_CASE_P(HttpStatusLineValidator,
+ ValidatorTest,
+ testing::ValuesIn(validator_tests),
+ TestName);
+
+} // namespace
+} // namespace net
diff --git a/chromium/net/http/http_stream.h b/chromium/net/http/http_stream.h
index 3e8703d1b23..1febd11ae95 100644
--- a/chromium/net/http/http_stream.h
+++ b/chromium/net/http/http_stream.h
@@ -11,6 +11,8 @@
#ifndef NET_HTTP_HTTP_STREAM_H_
#define NET_HTTP_HTTP_STREAM_H_
+#include <stdint.h>
+
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/completion_callback.h"
@@ -26,6 +28,7 @@ class HttpRequestHeaders;
struct HttpRequestInfo;
class HttpResponseInfo;
class IOBuffer;
+class IPEndPoint;
struct LoadTimingInfo;
class SSLCertRequestInfo;
class SSLInfo;
@@ -89,37 +92,37 @@ class NET_EXPORT_PRIVATE HttpStream {
// In the case of HTTP, where we re-use the byte-stream (e.g. the connection)
// this means we need to close the connection; in the case of SPDY, where the
// underlying stream is never reused, it has no effect.
- // TODO(mbelshe): We should figure out how to fold the not_reusable flag
- // into the stream implementation itself so that the caller
- // does not need to pass it at all. We might also be able to
- // eliminate the SetConnectionReused() below.
+ // TODO(mmenke): We should fold the |not_reusable| flag into the stream
+ // implementation itself so that the caller does not need to
+ // pass it at all. Ideally we'd be able to remove
+ // CanReuseConnection() and IsResponseBodyComplete().
+ // TODO(mmenke): We should try and merge Drain() into this method as well.
virtual void Close(bool not_reusable) = 0;
// Indicates if the response body has been completely read.
virtual bool IsResponseBodyComplete() const = 0;
- // Indicates that the end of the response is detectable. This means that
- // the response headers indicate either chunked encoding or content length.
- // If neither is sent, the server must close the connection for us to detect
- // the end of the response.
- // TODO(rch): Rename this method, so that it is clear why it exists
- // particularly as it applies to QUIC and SPDY for which the end of the
- // response is always findable.
- virtual bool CanFindEndOfResponse() const = 0;
-
// A stream exists on top of a connection. If the connection has been used
// to successfully exchange data in the past, error handling for the
// stream is done differently. This method returns true if the underlying
// connection is reused or has been connected and idle for some time.
virtual bool IsConnectionReused() const = 0;
+ // TODO(mmenke): We should fold this into RenewStreamForAuth(), and make that
+ // method drain the stream as well, if needed (And return asynchronously).
virtual void SetConnectionReused() = 0;
- // Checks whether the current state of the underlying connection
- // allows it to be reused.
- virtual bool IsConnectionReusable() const = 0;
+ // Checks whether the underlying connection can be reused. The stream's
+ // connection can be reused if the response headers allow for it, the socket
+ // is still connected, and the stream exclusively owns the underlying
+ // connection. SPDY and QUIC streams don't own their own connections, so
+ // always return false.
+ virtual bool CanReuseConnection() const = 0;
// Get the total number of bytes received from network for this stream.
- virtual int64 GetTotalReceivedBytes() const = 0;
+ virtual int64_t GetTotalReceivedBytes() const = 0;
+
+ // Get the total number of bytes sent over the network for this stream.
+ virtual int64_t GetTotalSentBytes() const = 0;
// Populates the connection establishment part of |load_timing_info|, and
// socket ID. |load_timing_info| must have all null times when called.
@@ -142,9 +145,10 @@ class NET_EXPORT_PRIVATE HttpStream {
// behavior is undefined.
virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) = 0;
- // HACK(willchan): Really, we should move the HttpResponseDrainer logic into
- // the HttpStream implementation. This is just a quick hack.
- virtual bool IsSpdyHttpStream() const = 0;
+ // Gets the remote endpoint of the socket that the HTTP stream is using, if
+ // any. Returns true and fills in |endpoint| if it is available; returns false
+ // and does not modify |endpoint| if it is unavailable.
+ virtual bool GetRemoteEndpoint(IPEndPoint* endpoint) = 0;
// In the case of an HTTP error or redirect, flush the response body (usually
// a simple error or "this page has moved") so that we can re-use the
diff --git a/chromium/net/http/http_stream_factory.cc b/chromium/net/http/http_stream_factory.cc
index 2ffe50724c1..1b6e66fccef 100644
--- a/chromium/net/http/http_stream_factory.cc
+++ b/chromium/net/http/http_stream_factory.cc
@@ -8,9 +8,12 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
+#include "base/time/time.h"
#include "net/base/host_mapping_rules.h"
#include "net/base/host_port_pair.h"
+#include "net/base/port_util.h"
#include "net/http/http_network_session.h"
+#include "net/spdy/spdy_alt_svc_wire_format.h"
#include "url/gurl.h"
namespace net {
@@ -28,6 +31,44 @@ void HttpStreamFactory::ResetStaticSettingsToInit() {
spdy_enabled_ = true;
}
+void HttpStreamFactory::ProcessAlternativeService(
+ const base::WeakPtr<HttpServerProperties>& http_server_properties,
+ base::StringPiece alternative_service_str,
+ const HostPortPair& http_host_port_pair,
+ const HttpNetworkSession& session) {
+ SpdyAltSvcWireFormat::AlternativeServiceVector alternative_service_vector;
+ if (!SpdyAltSvcWireFormat::ParseHeaderFieldValue(
+ alternative_service_str, &alternative_service_vector)) {
+ return;
+ }
+
+ // Convert SpdyAltSvcWireFormat::AlternativeService entries
+ // to net::AlternativeServiceInfo.
+ AlternativeServiceInfoVector alternative_service_info_vector;
+ for (const SpdyAltSvcWireFormat::AlternativeService&
+ alternative_service_entry : alternative_service_vector) {
+ AlternateProtocol protocol =
+ AlternateProtocolFromString(alternative_service_entry.protocol_id);
+ if (!IsAlternateProtocolValid(protocol) ||
+ !session.IsProtocolEnabled(protocol) ||
+ !IsPortValid(alternative_service_entry.port)) {
+ continue;
+ }
+ AlternativeService alternative_service(protocol,
+ alternative_service_entry.host,
+ alternative_service_entry.port);
+ base::Time expiration =
+ base::Time::Now() +
+ base::TimeDelta::FromSeconds(alternative_service_entry.max_age);
+ AlternativeServiceInfo alternative_service_info(
+ alternative_service, alternative_service_entry.p, expiration);
+ alternative_service_info_vector.push_back(alternative_service_info);
+ }
+
+ http_server_properties->SetAlternativeServices(
+ RewriteHost(http_host_port_pair), alternative_service_info_vector);
+}
+
void HttpStreamFactory::ProcessAlternateProtocol(
const base::WeakPtr<HttpServerProperties>& http_server_properties,
const std::vector<std::string>& alternate_protocol_values,
@@ -90,14 +131,10 @@ void HttpStreamFactory::ProcessAlternateProtocol(
return;
}
- HostPortPair host_port(http_host_port_pair);
- const HostMappingRules* mapping_rules = GetHostMappingRules();
- if (mapping_rules)
- mapping_rules->RewriteHost(&host_port);
-
http_server_properties->SetAlternativeService(
- host_port, AlternativeService(protocol, "", static_cast<uint16>(port)),
- probability);
+ RewriteHost(http_host_port_pair),
+ AlternativeService(protocol, "", static_cast<uint16>(port)), probability,
+ base::Time::Now() + base::TimeDelta::FromDays(1));
}
GURL HttpStreamFactory::ApplyHostMappingRules(const GURL& url,
@@ -116,4 +153,11 @@ GURL HttpStreamFactory::ApplyHostMappingRules(const GURL& url,
HttpStreamFactory::HttpStreamFactory() {}
+HostPortPair HttpStreamFactory::RewriteHost(HostPortPair host_port_pair) {
+ const HostMappingRules* mapping_rules = GetHostMappingRules();
+ if (mapping_rules)
+ mapping_rules->RewriteHost(&host_port_pair);
+ return host_port_pair;
+}
+
} // namespace net
diff --git a/chromium/net/http/http_stream_factory.h b/chromium/net/http/http_stream_factory.h
index 114af88c7e2..231271dffe7 100644
--- a/chromium/net/http/http_stream_factory.h
+++ b/chromium/net/http/http_stream_factory.h
@@ -184,6 +184,12 @@ class NET_EXPORT HttpStreamFactory {
public:
virtual ~HttpStreamFactory();
+ void ProcessAlternativeService(
+ const base::WeakPtr<HttpServerProperties>& http_server_properties,
+ base::StringPiece alternative_service_str,
+ const HostPortPair& http_host_port_pair,
+ const HttpNetworkSession& session);
+
void ProcessAlternateProtocol(
const base::WeakPtr<HttpServerProperties>& http_server_properties,
const std::vector<std::string>& alternate_protocol_values,
@@ -219,7 +225,6 @@ class NET_EXPORT HttpStreamFactory {
// Requests that enough connections for |num_streams| be opened.
virtual void PreconnectStreams(int num_streams,
const HttpRequestInfo& info,
- RequestPriority priority,
const SSLConfig& server_ssl_config,
const SSLConfig& proxy_ssl_config) = 0;
@@ -244,6 +249,8 @@ class NET_EXPORT HttpStreamFactory {
private:
static bool spdy_enabled_;
+ HostPortPair RewriteHost(HostPortPair host_port_pair);
+
DISALLOW_COPY_AND_ASSIGN(HttpStreamFactory);
};
diff --git a/chromium/net/http/http_stream_factory_impl.cc b/chromium/net/http/http_stream_factory_impl.cc
index 624bdced9b4..2a8664e51a6 100644
--- a/chromium/net/http/http_stream_factory_impl.cc
+++ b/chromium/net/http/http_stream_factory_impl.cc
@@ -124,7 +124,6 @@ HttpStreamRequest* HttpStreamFactoryImpl::RequestStreamInternal(
void HttpStreamFactoryImpl::PreconnectStreams(
int num_streams,
const HttpRequestInfo& request_info,
- RequestPriority priority,
const SSLConfig& server_ssl_config,
const SSLConfig& proxy_ssl_config) {
DCHECK(!for_websockets_);
@@ -135,8 +134,13 @@ void HttpStreamFactoryImpl::PreconnectStreams(
// TODO(bnc): Pass on multiple alternative services to Job.
alternative_service = alternative_service_vector[0];
}
+
+ // Due to how the socket pools handle priorities and idle sockets, only IDLE
+ // priority currently makes sense for preconnects. The priority for
+ // preconnects is currently ignored (see RequestSocketsForPool()), but could
+ // be used at some point for proxy resolution or something.
Job* job =
- new Job(this, session_, request_info, priority, server_ssl_config,
+ new Job(this, session_, request_info, IDLE, server_ssl_config,
proxy_ssl_config, alternative_service, session_->net_log());
preconnect_job_set_.insert(job);
job->Preconnect(num_streams);
@@ -148,9 +152,6 @@ const HostMappingRules* HttpStreamFactoryImpl::GetHostMappingRules() const {
AlternativeServiceVector HttpStreamFactoryImpl::GetAlternativeServicesFor(
const GURL& original_url) {
- if (!session_->params().use_alternate_protocols)
- return AlternativeServiceVector();
-
if (original_url.SchemeIs("ftp"))
return AlternativeServiceVector();
@@ -162,6 +163,9 @@ AlternativeServiceVector HttpStreamFactoryImpl::GetAlternativeServicesFor(
if (alternative_service_vector.empty())
return AlternativeServiceVector();
+ const bool enable_different_host =
+ session_->params().use_alternative_services;
+
AlternativeServiceVector enabled_alternative_service_vector;
for (const AlternativeService& alternative_service :
alternative_service_vector) {
@@ -172,6 +176,9 @@ AlternativeServiceVector HttpStreamFactoryImpl::GetAlternativeServicesFor(
continue;
}
+ if (origin.host() != alternative_service.host && !enable_different_host)
+ continue;
+
// Some shared unix systems may have user home directories (like
// http://foo.com/~mike) which allow users to emit headers. This is a bad
// idea already, but with Alternate-Protocol, it provides the ability for a
@@ -204,7 +211,7 @@ AlternativeServiceVector HttpStreamFactoryImpl::GetAlternativeServicesFor(
if (session_->quic_stream_factory()->IsQuicDisabled(origin.port()))
continue;
- if (session_->params().disable_insecure_quic &&
+ if (!session_->params().enable_insecure_quic &&
!original_url.SchemeIs("https")) {
continue;
}
diff --git a/chromium/net/http/http_stream_factory_impl.h b/chromium/net/http/http_stream_factory_impl.h
index 8194f29f378..1ac451dd99e 100644
--- a/chromium/net/http/http_stream_factory_impl.h
+++ b/chromium/net/http/http_stream_factory_impl.h
@@ -50,7 +50,6 @@ class NET_EXPORT_PRIVATE HttpStreamFactoryImpl : public HttpStreamFactory {
void PreconnectStreams(int num_streams,
const HttpRequestInfo& info,
- RequestPriority priority,
const SSLConfig& server_ssl_config,
const SSLConfig& proxy_ssl_config) override;
const HostMappingRules* GetHostMappingRules() const override;
diff --git a/chromium/net/http/http_stream_factory_impl_job.cc b/chromium/net/http/http_stream_factory_impl_job.cc
index 004549902df..8955017cded 100644
--- a/chromium/net/http/http_stream_factory_impl_job.cc
+++ b/chromium/net/http/http_stream_factory_impl_job.cc
@@ -23,6 +23,7 @@
#include "build/build_config.h"
#include "net/base/connection_type_histograms.h"
#include "net/base/net_util.h"
+#include "net/base/port_util.h"
#include "net/cert/cert_verifier.h"
#include "net/http/http_basic_stream.h"
#include "net/http/http_network_session.h"
@@ -214,16 +215,18 @@ void HttpStreamFactoryImpl::Job::WaitFor(Job* job) {
job->waiting_job_ = this;
}
-void HttpStreamFactoryImpl::Job::Resume(Job* job) {
+void HttpStreamFactoryImpl::Job::Resume(Job* job,
+ const base::TimeDelta& delay) {
DCHECK_EQ(blocking_job_, job);
blocking_job_ = NULL;
// We know we're blocked if the next_state_ is STATE_WAIT_FOR_JOB_COMPLETE.
// Unblock |this|.
if (next_state_ == STATE_WAIT_FOR_JOB_COMPLETE) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, base::Bind(&HttpStreamFactoryImpl::Job::OnIOComplete,
- ptr_factory_.GetWeakPtr(), OK));
+ ptr_factory_.GetWeakPtr(), OK),
+ delay);
}
}
@@ -678,7 +681,7 @@ int HttpStreamFactoryImpl::Job::DoStart() {
// Don't connect to restricted ports.
if (!IsPortAllowedForScheme(server_.port(), request_info_.url.scheme())) {
if (waiting_job_) {
- waiting_job_->Resume(this);
+ waiting_job_->Resume(this, base::TimeDelta());
waiting_job_ = NULL;
}
return ERR_UNSAFE_PORT;
@@ -753,7 +756,7 @@ int HttpStreamFactoryImpl::Job::DoResolveProxyComplete(int result) {
if (result != OK) {
if (waiting_job_) {
- waiting_job_->Resume(this);
+ waiting_job_->Resume(this, base::TimeDelta());
waiting_job_ = NULL;
}
return result;
@@ -859,7 +862,17 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() {
// OK, there's no available QUIC session. Let |waiting_job_| resume
// if it's paused.
if (waiting_job_) {
- waiting_job_->Resume(this);
+ if (rv == ERR_IO_PENDING) {
+ // Start the |waiting_job_| after the delay returned by
+ // GetTimeDelayForWaitingJob().
+ //
+ // If QUIC request fails during handshake, then
+ // DoInitConnectionComplete() will start the |waiting_job_|.
+ waiting_job_->Resume(this, quic_request_.GetTimeDelayForWaitingJob());
+ } else {
+ // QUIC request has failed, resume the |waiting_job_|.
+ waiting_job_->Resume(this, base::TimeDelta());
+ }
waiting_job_ = NULL;
}
}
@@ -895,7 +908,7 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() {
// OK, there's no available SPDY session. Let |waiting_job_| resume if it's
// paused.
if (waiting_job_) {
- waiting_job_->Resume(this);
+ waiting_job_->Resume(this, base::TimeDelta());
waiting_job_ = NULL;
}
@@ -950,6 +963,10 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() {
}
int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) {
+ if (using_quic_ && result < 0 && waiting_job_) {
+ waiting_job_->Resume(this, base::TimeDelta());
+ waiting_job_ = NULL;
+ }
if (IsPreconnecting()) {
if (using_quic_)
return result;
@@ -976,7 +993,7 @@ int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) {
if (proxy_info_.is_quic() && using_quic_) {
if (result == ERR_QUIC_PROTOCOL_ERROR ||
- result == ERR_QUIC_HANDSHAKE_FAILED) {
+ result == ERR_QUIC_HANDSHAKE_FAILED || result == ERR_MSG_TOO_BIG) {
using_quic_ = false;
return ReconsiderProxyAfterError(result);
}
@@ -992,7 +1009,7 @@ int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) {
// TODO(willchan): Make this a bit more exact. Maybe there are recoverable
// errors, such as ignoring certificate errors for Alternate-Protocol.
if (result < 0 && waiting_job_) {
- waiting_job_->Resume(this);
+ waiting_job_->Resume(this, base::TimeDelta());
waiting_job_ = NULL;
}
@@ -1376,6 +1393,7 @@ int HttpStreamFactoryImpl::Job::ReconsiderProxyAfterError(int error) {
// captive portal).
case ERR_QUIC_PROTOCOL_ERROR:
case ERR_QUIC_HANDSHAKE_FAILED:
+ case ERR_MSG_TOO_BIG:
case ERR_SSL_PROTOCOL_ERROR:
break;
case ERR_SOCKS_CONNECTION_HOST_UNREACHABLE:
@@ -1392,9 +1410,12 @@ int HttpStreamFactoryImpl::Job::ReconsiderProxyAfterError(int error) {
return error;
}
- if (request_info_.load_flags & LOAD_BYPASS_PROXY) {
+ // Do not bypass non-QUIC proxy on ERR_MSG_TOO_BIG.
+ if (!proxy_info_.is_quic() && error == ERR_MSG_TOO_BIG)
+ return error;
+
+ if (request_info_.load_flags & LOAD_BYPASS_PROXY)
return error;
- }
if (proxy_info_.is_https() && proxy_ssl_config_.send_client_cert) {
session_->ssl_client_auth_cache()->Remove(
diff --git a/chromium/net/http/http_stream_factory_impl_job.h b/chromium/net/http/http_stream_factory_impl_job.h
index 637e3b1dda5..81b812a6083 100644
--- a/chromium/net/http/http_stream_factory_impl_job.h
+++ b/chromium/net/http/http_stream_factory_impl_job.h
@@ -8,6 +8,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
#include "net/base/completion_callback.h"
#include "net/base/request_priority.h"
#include "net/http/http_auth.h"
@@ -70,9 +71,10 @@ class HttpStreamFactoryImpl::Job {
void WaitFor(Job* job);
// Tells |this| that |job| has determined it still needs to continue
- // connecting, so allow |this| to continue. If this is not called, then
- // |request_| is expected to cancel |this| by deleting it.
- void Resume(Job* job);
+ // connecting, so allow |this| to continue after the specified |delay|. If
+ // this is not called, then |request_| is expected to cancel |this| by
+ // deleting it.
+ void Resume(Job* job, const base::TimeDelta& delay);
// Used to detach the Job from |request|.
void Orphan(const Request* request);
diff --git a/chromium/net/http/http_stream_factory_impl_request_unittest.cc b/chromium/net/http/http_stream_factory_impl_request_unittest.cc
index 0e31c1ec05c..7a5483155bf 100644
--- a/chromium/net/http/http_stream_factory_impl_request_unittest.cc
+++ b/chromium/net/http/http_stream_factory_impl_request_unittest.cc
@@ -4,6 +4,7 @@
#include "net/http/http_stream_factory_impl_request.h"
+#include "base/memory/scoped_ptr.h"
#include "net/http/http_stream_factory_impl_job.h"
#include "net/proxy/proxy_info.h"
#include "net/proxy/proxy_service.h"
@@ -20,7 +21,6 @@ class HttpStreamFactoryImplRequestTest
INSTANTIATE_TEST_CASE_P(NextProto,
HttpStreamFactoryImplRequestTest,
testing::Values(kProtoSPDY31,
- kProtoHTTP2_14,
kProtoHTTP2));
namespace {
diff --git a/chromium/net/http/http_stream_factory_impl_unittest.cc b/chromium/net/http/http_stream_factory_impl_unittest.cc
index f94f8b25605..ed61ebfb0be 100644
--- a/chromium/net/http/http_stream_factory_impl_unittest.cc
+++ b/chromium/net/http/http_stream_factory_impl_unittest.cc
@@ -4,11 +4,14 @@
#include "net/http/http_stream_factory_impl.h"
+#include <stdint.h>
+
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "net/base/port_util.h"
#include "net/base/test_completion_callback.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/dns/mock_host_resolver.h"
@@ -80,17 +83,17 @@ class MockWebSocketHandshakeStream : public WebSocketHandshakeStreamBase {
}
void Close(bool not_reusable) override {}
bool IsResponseBodyComplete() const override { return false; }
- bool CanFindEndOfResponse() const override { return false; }
bool IsConnectionReused() const override { return false; }
void SetConnectionReused() override {}
- bool IsConnectionReusable() const override { return false; }
- int64 GetTotalReceivedBytes() const override { return 0; }
+ bool CanReuseConnection() const override { return false; }
+ int64_t GetTotalReceivedBytes() const override { return 0; }
+ int64_t GetTotalSentBytes() const override { return 0; }
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
return false;
}
void GetSSLInfo(SSLInfo* ssl_info) override {}
void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {}
- bool IsSpdyHttpStream() const override { return false; }
+ bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
void Drain(HttpNetworkSession* session) override {}
void SetPriority(RequestPriority priority) override {}
UploadProgress GetUploadProgress() const override { return UploadProgress(); }
@@ -300,17 +303,17 @@ void PreconnectHelperForURL(int num_streams,
request.url = url;
request.load_flags = 0;
- session->http_stream_factory()->PreconnectStreams(
- num_streams, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
+ session->http_stream_factory()->PreconnectStreams(num_streams, request,
+ ssl_config, ssl_config);
mock_factory->WaitForPreconnects();
-};
+}
void PreconnectHelper(const TestCase& test,
HttpNetworkSession* session) {
GURL url = test.ssl ? GURL("https://www.google.com") :
GURL("http://www.google.com");
PreconnectHelperForURL(test.num_streams, url, session);
-};
+}
template<typename ParentPool>
class CapturePreconnectsSocketPool : public ParentPool {
@@ -422,7 +425,6 @@ class HttpStreamFactoryTest : public ::testing::Test,
INSTANTIATE_TEST_CASE_P(NextProto,
HttpStreamFactoryTest,
testing::Values(kProtoSPDY31,
- kProtoHTTP2_14,
kProtoHTTP2));
TEST_P(HttpStreamFactoryTest, PreconnectDirect) {
@@ -613,13 +615,12 @@ TEST_P(HttpStreamFactoryTest, JobNotifiesProxy) {
}
TEST_P(HttpStreamFactoryTest, UnreachableQuicProxyMarkedAsBad) {
- for (int i = 1; i <= 2; i++) {
- int mock_error =
- i == 1 ? ERR_QUIC_PROTOCOL_ERROR : ERR_QUIC_HANDSHAKE_FAILED;
-
+ const int mock_error[] = {ERR_QUIC_PROTOCOL_ERROR, ERR_QUIC_HANDSHAKE_FAILED,
+ ERR_MSG_TOO_BIG};
+ for (size_t i = 0; i < arraysize(mock_error); ++i) {
scoped_ptr<ProxyService> proxy_service;
- proxy_service.reset(
- ProxyService::CreateFixedFromPacResult("QUIC bad:99; DIRECT"));
+ proxy_service =
+ ProxyService::CreateFixedFromPacResult("QUIC bad:99; DIRECT");
HttpNetworkSession::Params params;
params.enable_quic = true;
@@ -642,7 +643,7 @@ TEST_P(HttpStreamFactoryTest, UnreachableQuicProxyMarkedAsBad) {
session->quic_stream_factory()->set_require_confirmation(false);
StaticSocketDataProvider socket_data1;
- socket_data1.set_connect_data(MockConnect(ASYNC, mock_error));
+ socket_data1.set_connect_data(MockConnect(ASYNC, mock_error[i]));
socket_factory.AddSocketDataProvider(&socket_data1);
// Second connection attempt succeeds.
@@ -667,11 +668,11 @@ TEST_P(HttpStreamFactoryTest, UnreachableQuicProxyMarkedAsBad) {
// The proxy that failed should now be known to the proxy_service as bad.
const ProxyRetryInfoMap& retry_info =
session->proxy_service()->proxy_retry_info();
- EXPECT_EQ(1u, retry_info.size()) << i;
+ EXPECT_EQ(1u, retry_info.size()) << mock_error[i];
EXPECT_TRUE(waiter.used_proxy_info().is_direct());
ProxyRetryInfoMap::const_iterator iter = retry_info.find("quic://bad:99");
- EXPECT_TRUE(iter != retry_info.end()) << i;
+ EXPECT_TRUE(iter != retry_info.end()) << mock_error[i];
}
}
@@ -680,8 +681,7 @@ TEST_P(HttpStreamFactoryTest, UnreachableQuicProxyMarkedAsBad) {
TEST_P(HttpStreamFactoryTest, QuicLossyProxyMarkedAsBad) {
// Checks if a
scoped_ptr<ProxyService> proxy_service;
- proxy_service.reset(
- ProxyService::CreateFixedFromPacResult("QUIC bad:99; DIRECT"));
+ proxy_service = ProxyService::CreateFixedFromPacResult("QUIC bad:99; DIRECT");
HttpNetworkSession::Params params;
params.enable_quic = true;
@@ -778,6 +778,7 @@ TEST_P(HttpStreamFactoryTest, PrivacyModeDisablesChannelId) {
}
namespace {
+
// Return count of distinct groups in given socket pool.
int GetSocketPoolGroupCount(ClientSocketPool* pool) {
int count = 0;
@@ -789,6 +790,17 @@ int GetSocketPoolGroupCount(ClientSocketPool* pool) {
}
return count;
}
+
+// Return count of distinct spdy sessions.
+int GetSpdySessionCount(HttpNetworkSession* session) {
+ scoped_ptr<base::Value> value(
+ session->spdy_session_pool()->SpdySessionPoolInfoToValue());
+ base::ListValue* session_list;
+ if (!value || !value->GetAsList(&session_list))
+ return -1;
+ return session_list->GetSize();
+}
+
} // namespace
TEST_P(HttpStreamFactoryTest, PrivacyModeUsesDifferentSocketPoolGroup) {
@@ -903,8 +915,8 @@ TEST_P(HttpStreamFactoryTest, RequestHttpStream) {
EXPECT_TRUE(waiter.stream_done());
ASSERT_TRUE(nullptr != waiter.stream());
EXPECT_TRUE(nullptr == waiter.websocket_stream());
- EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream());
+ EXPECT_EQ(0, GetSpdySessionCount(session.get()));
EXPECT_EQ(1, GetSocketPoolGroupCount(
session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool(
@@ -952,7 +964,8 @@ TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverSSL) {
EXPECT_TRUE(waiter.stream_done());
ASSERT_TRUE(nullptr != waiter.stream());
EXPECT_TRUE(nullptr == waiter.websocket_stream());
- EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream());
+
+ EXPECT_EQ(0, GetSpdySessionCount(session.get()));
EXPECT_EQ(1, GetSocketPoolGroupCount(
session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
EXPECT_EQ(1, GetSocketPoolGroupCount(
@@ -997,7 +1010,8 @@ TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverProxy) {
EXPECT_TRUE(waiter.stream_done());
ASSERT_TRUE(nullptr != waiter.stream());
EXPECT_TRUE(nullptr == waiter.websocket_stream());
- EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream());
+
+ EXPECT_EQ(0, GetSpdySessionCount(session.get()));
EXPECT_EQ(0, GetSocketPoolGroupCount(
session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
EXPECT_EQ(0, GetSocketPoolGroupCount(
@@ -1169,7 +1183,7 @@ TEST_P(HttpStreamFactoryTest, RequestSpdyHttpStream) {
SpdySessionDependencies session_deps(GetParam(),
ProxyService::CreateDirect());
- MockRead mock_read(ASYNC, OK);
+ MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
SequencedSocketData socket_data(&mock_read, 1, nullptr, 0);
socket_data.set_connect_data(MockConnect(ASYNC, OK));
session_deps.socket_factory->AddSocketDataProvider(&socket_data);
@@ -1202,7 +1216,8 @@ TEST_P(HttpStreamFactoryTest, RequestSpdyHttpStream) {
EXPECT_TRUE(waiter.stream_done());
EXPECT_TRUE(nullptr == waiter.websocket_stream());
ASSERT_TRUE(nullptr != waiter.stream());
- EXPECT_TRUE(waiter.stream()->IsSpdyHttpStream());
+
+ EXPECT_EQ(1, GetSpdySessionCount(session.get()));
EXPECT_EQ(1, GetSocketPoolGroupCount(
session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
EXPECT_EQ(1, GetSocketPoolGroupCount(
@@ -1349,7 +1364,7 @@ TEST_P(HttpStreamFactoryTest, DISABLED_RequestWebSocketSpdyHandshakeStream) {
TEST_P(HttpStreamFactoryTest, DISABLED_OrphanedWebSocketStream) {
SpdySessionDependencies session_deps(GetParam(),
ProxyService::CreateDirect());
- session_deps.use_alternate_protocols = true;
+ session_deps.use_alternative_services = true;
MockRead mock_read(ASYNC, OK);
SequencedSocketData socket_data(&mock_read, 1, nullptr, 0);
@@ -1374,9 +1389,10 @@ TEST_P(HttpStreamFactoryTest, DISABLED_OrphanedWebSocketStream) {
request_info.url = GURL("ws://www.google.com:8888");
request_info.load_flags = 0;
+ base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
session->http_server_properties()->SetAlternativeService(
HostPortPair("www.google.com", 8888),
- AlternativeService(NPN_HTTP_2, "www.google.com", 9999), 1.0);
+ AlternativeService(NPN_HTTP_2, "www.google.com", 9999), 1.0, expiration);
SSLConfig ssl_config;
StreamRequestWaiter waiter;
diff --git a/chromium/net/http/http_stream_parser.cc b/chromium/net/http/http_stream_parser.cc
index 3c3b88d76d9..9ddae4853da 100644
--- a/chromium/net/http/http_stream_parser.cc
+++ b/chromium/net/http/http_stream_parser.cc
@@ -18,6 +18,7 @@
#include "net/http/http_request_headers.h"
#include "net/http/http_request_info.h"
#include "net/http/http_response_headers.h"
+#include "net/http/http_status_line_validator.h"
#include "net/http/http_util.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/ssl_client_socket.h"
@@ -28,10 +29,13 @@ namespace {
enum HttpHeaderParserEvent {
HEADER_PARSER_INVOKED = 0,
- HEADER_HTTP_09_RESPONSE = 1,
+ // Obsolete: HEADER_HTTP_09_RESPONSE = 1,
HEADER_ALLOWED_TRUNCATED_HEADERS = 2,
HEADER_SKIPPED_WS_PREFIX = 3,
HEADER_SKIPPED_NON_WS_PREFIX = 4,
+ HEADER_HTTP_09_RESPONSE_OVER_HTTP = 5,
+ HEADER_HTTP_09_RESPONSE_OVER_SSL = 6,
+ HEADER_HTTP_09_ON_REUSED_SOCKET = 7,
NUM_HEADER_EVENTS
};
@@ -198,15 +202,17 @@ HttpStreamParser::HttpStreamParser(ClientSocketHandle* connection,
const BoundNetLog& net_log)
: io_state_(STATE_NONE),
request_(request),
- request_headers_(NULL),
+ request_headers_(nullptr),
request_headers_length_(0),
read_buf_(read_buffer),
read_buf_unused_offset_(0),
response_header_start_offset_(-1),
received_bytes_(0),
+ sent_bytes_(0),
+ response_(nullptr),
response_body_length_(-1),
response_body_read_(0),
- user_read_buf_(NULL),
+ user_read_buf_(nullptr),
user_read_buf_len_(0),
connection_(connection),
net_log_(net_log),
@@ -470,6 +476,7 @@ int HttpStreamParser::DoSendHeadersComplete(int result) {
return result;
}
+ sent_bytes_ += result;
request_headers_->DidConsume(result);
if (request_headers_->BytesRemaining() > 0) {
io_state_ = STATE_SEND_HEADERS;
@@ -527,6 +534,7 @@ int HttpStreamParser::DoSendBodyComplete(int result) {
return result;
}
+ sent_bytes_ += result;
request_body_send_buf_->DidConsume(result);
io_state_ = STATE_SEND_BODY;
@@ -768,37 +776,40 @@ int HttpStreamParser::HandleReadHeaderResult(int result) {
if (result == 0)
result = ERR_CONNECTION_CLOSED;
- if (result < 0 && result != ERR_CONNECTION_CLOSED) {
- io_state_ = STATE_DONE;
- return result;
- }
- // If we've used the connection before, then we know it is not a HTTP/0.9
- // response and return ERR_CONNECTION_CLOSED.
- if (result == ERR_CONNECTION_CLOSED && read_buf_->offset() == 0 &&
- connection_->is_reused()) {
- io_state_ = STATE_DONE;
- return result;
- }
-
- // Record our best estimate of the 'response time' as the time when we read
- // the first bytes of the response headers.
- if (read_buf_->offset() == 0 && result != ERR_CONNECTION_CLOSED)
- response_->response_time = base::Time::Now();
-
if (result == ERR_CONNECTION_CLOSED) {
- // The connection closed before we detected the end of the headers.
+ // The connection closed without getting any more data.
if (read_buf_->offset() == 0) {
- // The connection was closed before any data was sent. Likely an error
- // rather than empty HTTP/0.9 response.
io_state_ = STATE_DONE;
- return ERR_EMPTY_RESPONSE;
- } else if (request_->url.SchemeIsCryptographic()) {
- // The connection was closed in the middle of the headers. For HTTPS we
- // don't parse partial headers. Return a different error code so that we
- // know that we shouldn't attempt to retry the request.
+ // If the connection has not been reused, it may have been a 0-length
+ // HTTP/0.9 responses, but it was most likely an error, so just return
+ // ERR_EMPTY_RESPONSE instead. If the connection was reused, just pass
+ // on the original connection close error, as rather than being an
+ // empty HTTP/0.9 response it's much more likely the server closed the
+ // socket before it received the request.
+ if (!connection_->is_reused())
+ return ERR_EMPTY_RESPONSE;
+ return result;
+ }
+
+ // Accepting truncated headers over HTTPS is a potential security
+ // vulnerability, so just return an error in that case.
+ //
+ // If response_header_start_offset_ is -1, this may be a < 8 byte HTTP/0.9
+ // response. However, accepting such a response over HTTPS would allow a
+ // MITM to truncate an HTTP/1.x status line to look like a short HTTP/0.9
+ // response if the peer put a record boundary at the first 8 bytes. To
+ // ensure that all response headers received over HTTPS are pristine, treat
+ // such responses as errors.
+ //
+ // TODO(mmenke): Returning ERR_RESPONSE_HEADERS_TRUNCATED when a response
+ // looks like an HTTP/0.9 response is weird. Should either come up with
+ // another error code, or, better, disable HTTP/0.9 over HTTPS (and give
+ // that a new error code).
+ if (request_->url.SchemeIsCryptographic()) {
io_state_ = STATE_DONE;
return ERR_RESPONSE_HEADERS_TRUNCATED;
}
+
// Parse things as well as we can and let the caller decide what to do.
int end_offset;
if (response_header_start_offset_ >= 0) {
@@ -808,7 +819,7 @@ int HttpStreamParser::HandleReadHeaderResult(int result) {
RecordHeaderParserEvent(HEADER_ALLOWED_TRUNCATED_HEADERS);
} else {
// The response is apparently using HTTP/0.9. Treat the entire response
- // the body.
+ // as the body.
end_offset = 0;
}
int rv = ParseResponseHeaders(end_offset);
@@ -817,6 +828,16 @@ int HttpStreamParser::HandleReadHeaderResult(int result) {
return result;
}
+ if (result < 0) {
+ io_state_ = STATE_DONE;
+ return result;
+ }
+
+ // Record our best estimate of the 'response time' as the time when we read
+ // the first bytes of the response headers.
+ if (read_buf_->offset() == 0)
+ response_->response_time = base::Time::Now();
+
read_buf_->set_offset(read_buf_->offset() + result);
DCHECK_LE(read_buf_->offset(), read_buf_->capacity());
DCHECK_GE(result, 0);
@@ -924,38 +945,47 @@ int HttpStreamParser::ParseResponseHeaders(int end_offset) {
if (response_header_start_offset_ >= 0) {
received_bytes_ += end_offset;
- headers = new HttpResponseHeaders(HttpUtil::AssembleRawHeaders(
- read_buf_->StartOfBuffer(), end_offset));
+ std::string raw_headers =
+ HttpUtil::AssembleRawHeaders(read_buf_->StartOfBuffer(), end_offset);
+ ValidateStatusLine(
+ std::string(read_buf_->StartOfBuffer(), raw_headers.find('\0')));
+ headers = new HttpResponseHeaders(raw_headers);
} else {
// Enough data was read -- there is no status line.
headers = new HttpResponseHeaders(std::string("HTTP/0.9 200 OK"));
- RecordHeaderParserEvent(HEADER_HTTP_09_RESPONSE);
+
+ if (request_->url.SchemeIsCryptographic()) {
+ RecordHeaderParserEvent(HEADER_HTTP_09_RESPONSE_OVER_SSL);
+ } else {
+ RecordHeaderParserEvent(HEADER_HTTP_09_RESPONSE_OVER_HTTP);
+ }
+ if (connection_->is_reused())
+ RecordHeaderParserEvent(HEADER_HTTP_09_ON_REUSED_SOCKET);
}
- // Check for multiple Content-Length headers with no Transfer-Encoding header.
- // If they exist, and have distinct values, it's a potential response
- // smuggling attack.
- if (!headers->HasHeader("Transfer-Encoding")) {
- if (HeadersContainMultipleCopiesOfField(*headers.get(), "Content-Length"))
+ // Check for multiple Content-Length headers when the response is not
+ // chunked-encoded. If they exist, and have distinct values, it's a potential
+ // response smuggling attack.
+ if (!headers->IsChunkEncoded()) {
+ if (HeadersContainMultipleCopiesOfField(*headers, "Content-Length"))
return ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH;
}
// Check for multiple Content-Disposition or Location headers. If they exist,
// it's also a potential response smuggling attack.
- if (HeadersContainMultipleCopiesOfField(*headers.get(),
- "Content-Disposition"))
+ if (HeadersContainMultipleCopiesOfField(*headers, "Content-Disposition"))
return ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION;
- if (HeadersContainMultipleCopiesOfField(*headers.get(), "Location"))
+ if (HeadersContainMultipleCopiesOfField(*headers, "Location"))
return ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION;
response_->headers = headers;
response_->connection_info = HttpResponseInfo::CONNECTION_INFO_HTTP1;
- response_->vary_data.Init(*request_, *response_->headers.get());
+ response_->vary_data.Init(*request_, *response_->headers);
DVLOG(1) << __FUNCTION__ << "()"
<< " content_length = \"" << response_->headers->GetContentLength()
<< "\n\""
- << " headers = \""
- << GetResponseHeaderLines(*response_->headers.get()) << "\"";
+ << " headers = \"" << GetResponseHeaderLines(*response_->headers)
+ << "\"";
return OK;
}
@@ -1043,7 +1073,11 @@ void HttpStreamParser::SetConnectionReused() {
connection_->set_reuse_type(ClientSocketHandle::REUSED_IDLE);
}
-bool HttpStreamParser::IsConnectionReusable() const {
+bool HttpStreamParser::CanReuseConnection() const {
+ if (!CanFindEndOfResponse())
+ return false;
+ if (!response_->headers || !response_->headers->IsKeepAlive())
+ return false;
return connection_->socket() && connection_->socket()->IsConnectedAndIdle();
}
@@ -1103,4 +1137,11 @@ bool HttpStreamParser::ShouldMergeRequestHeadersAndBody(
return false;
}
+void HttpStreamParser::ValidateStatusLine(const std::string& status_line) {
+ HttpStatusLineValidator::StatusLineStatus status =
+ HttpStatusLineValidator::ValidateStatusLine(status_line);
+ UMA_HISTOGRAM_ENUMERATION("Net.HttpStatusLineStatus", status,
+ HttpStatusLineValidator::STATUS_LINE_MAX);
+}
+
} // namespace net
diff --git a/chromium/net/http/http_stream_parser.h b/chromium/net/http/http_stream_parser.h
index ea810196e7d..f56e7ded4c3 100644
--- a/chromium/net/http/http_stream_parser.h
+++ b/chromium/net/http/http_stream_parser.h
@@ -5,6 +5,8 @@
#ifndef NET_HTTP_HTTP_STREAM_PARSER_H_
#define NET_HTTP_HTTP_STREAM_PARSER_H_
+#include <stdint.h>
+
#include <string>
#include "base/basictypes.h"
@@ -73,9 +75,19 @@ class NET_EXPORT_PRIVATE HttpStreamParser {
void SetConnectionReused();
- bool IsConnectionReusable() const;
+ // Returns true if the underlying connection can be reused.
+ // The connection can be reused if:
+ // * It's still connected.
+ // * The response headers indicate the connection can be kept alive.
+ // * The end of the response can be found.
+ //
+ // Note that if response headers have yet to be received, this will return
+ // false.
+ bool CanReuseConnection() const;
+
+ int64_t received_bytes() const { return received_bytes_; }
- int64 received_bytes() const { return received_bytes_; }
+ int64_t sent_bytes() const { return sent_bytes_; }
void GetSSLInfo(SSLInfo* ssl_info);
@@ -169,6 +181,9 @@ class NET_EXPORT_PRIVATE HttpStreamParser {
// Examine the parsed headers to try to determine the response body size.
void CalculateResponseBodySize();
+ // Uploads statistics about status line compliance with RFC 7230.
+ void ValidateStatusLine(const std::string& status_line);
+
// Next state of the request, when the current one completes.
State io_state_;
@@ -196,7 +211,10 @@ class NET_EXPORT_PRIVATE HttpStreamParser {
// The amount of received data. If connection is reused then intermediate
// value may be bigger than final.
- int64 received_bytes_;
+ int64_t received_bytes_;
+
+ // The amount of sent data.
+ int64_t sent_bytes_;
// The parsed response headers. Owned by the caller of SendRequest. This
// cannot be safely accessed after reading the final set of headers, as the
diff --git a/chromium/net/http/http_stream_parser_unittest.cc b/chromium/net/http/http_stream_parser_unittest.cc
index 76f998a0e97..012960606c1 100644
--- a/chromium/net/http/http_stream_parser_unittest.cc
+++ b/chromium/net/http/http_stream_parser_unittest.cc
@@ -4,6 +4,8 @@
#include "net/http/http_stream_parser.h"
+#include <stdint.h>
+
#include <algorithm>
#include <string>
#include <vector>
@@ -199,6 +201,208 @@ TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_LargeBodyInMemory) {
"some header", body.get()));
}
+TEST(HttpStreamParser, SentBytesNoHeaders) {
+ MockWrite writes[] = {
+ MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n\r\n"),
+ };
+
+ SequencedSocketData data(nullptr, 0, writes, arraysize(writes));
+ scoped_ptr<ClientSocketHandle> socket_handle =
+ CreateConnectedSocketHandle(&data);
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://localhost");
+
+ scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
+ HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(),
+ BoundNetLog());
+
+ HttpResponseInfo response;
+ TestCompletionCallback callback;
+ EXPECT_EQ(OK, parser.SendRequest("GET / HTTP/1.1\r\n", HttpRequestHeaders(),
+ &response, callback.callback()));
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+}
+
+TEST(HttpStreamParser, SentBytesWithHeaders) {
+ MockWrite writes[] = {
+ MockWrite(SYNCHRONOUS, 0,
+ "GET / HTTP/1.1\r\n"
+ "Host: localhost\r\n"
+ "Connection: Keep-Alive\r\n\r\n"),
+ };
+
+ SequencedSocketData data(nullptr, 0, writes, arraysize(writes));
+ scoped_ptr<ClientSocketHandle> socket_handle =
+ CreateConnectedSocketHandle(&data);
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://localhost");
+
+ scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
+ HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(),
+ BoundNetLog());
+
+ HttpRequestHeaders headers;
+ headers.SetHeader("Host", "localhost");
+ headers.SetHeader("Connection", "Keep-Alive");
+
+ HttpResponseInfo response;
+ TestCompletionCallback callback;
+ EXPECT_EQ(OK, parser.SendRequest("GET / HTTP/1.1\r\n", headers, &response,
+ callback.callback()));
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+}
+
+TEST(HttpStreamParser, SentBytesWithHeadersMultiWrite) {
+ MockWrite writes[] = {
+ MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
+ MockWrite(SYNCHRONOUS, 1, "Host: localhost\r\n"),
+ MockWrite(SYNCHRONOUS, 2, "Connection: Keep-Alive\r\n\r\n"),
+ };
+
+ SequencedSocketData data(nullptr, 0, writes, arraysize(writes));
+ scoped_ptr<ClientSocketHandle> socket_handle =
+ CreateConnectedSocketHandle(&data);
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://localhost");
+
+ scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
+ HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(),
+ BoundNetLog());
+
+ HttpRequestHeaders headers;
+ headers.SetHeader("Host", "localhost");
+ headers.SetHeader("Connection", "Keep-Alive");
+
+ HttpResponseInfo response;
+ TestCompletionCallback callback;
+
+ EXPECT_EQ(OK, parser.SendRequest("GET / HTTP/1.1\r\n", headers, &response,
+ callback.callback()));
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+}
+
+TEST(HttpStreamParser, SentBytesWithErrorWritingHeaders) {
+ MockWrite writes[] = {
+ MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
+ MockWrite(SYNCHRONOUS, 1, "Host: localhost\r\n"),
+ MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET, 2),
+ };
+
+ SequencedSocketData data(nullptr, 0, writes, arraysize(writes));
+ scoped_ptr<ClientSocketHandle> socket_handle =
+ CreateConnectedSocketHandle(&data);
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://localhost");
+
+ scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
+ HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(),
+ BoundNetLog());
+
+ HttpRequestHeaders headers;
+ headers.SetHeader("Host", "localhost");
+ headers.SetHeader("Connection", "Keep-Alive");
+
+ HttpResponseInfo response;
+ TestCompletionCallback callback;
+ EXPECT_EQ(ERR_CONNECTION_RESET,
+ parser.SendRequest("GET / HTTP/1.1\r\n", headers, &response,
+ callback.callback()));
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+}
+
+TEST(HttpStreamParser, SentBytesPost) {
+ MockWrite writes[] = {
+ MockWrite(SYNCHRONOUS, 0, "POST / HTTP/1.1\r\n"),
+ MockWrite(SYNCHRONOUS, 1, "Content-Length: 12\r\n\r\n"),
+ MockWrite(SYNCHRONOUS, 2, "hello world!"),
+ };
+
+ SequencedSocketData data(nullptr, 0, writes, arraysize(writes));
+ scoped_ptr<ClientSocketHandle> socket_handle =
+ CreateConnectedSocketHandle(&data);
+
+ ScopedVector<UploadElementReader> element_readers;
+ element_readers.push_back(new UploadBytesElementReader("hello world!", 12));
+ ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ ASSERT_EQ(OK, upload_data_stream.Init(TestCompletionCallback().callback()));
+
+ HttpRequestInfo request;
+ request.method = "POST";
+ request.url = GURL("http://localhost");
+ request.upload_data_stream = &upload_data_stream;
+
+ scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
+ HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(),
+ BoundNetLog());
+
+ HttpRequestHeaders headers;
+ headers.SetHeader("Content-Length", "12");
+
+ HttpResponseInfo response;
+ TestCompletionCallback callback;
+ EXPECT_EQ(OK, parser.SendRequest("POST / HTTP/1.1\r\n", headers, &response,
+ callback.callback()));
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+}
+
+TEST(HttpStreamParser, SentBytesChunkedPostError) {
+ static const char kChunk[] = "Chunk 1";
+
+ MockWrite writes[] = {
+ MockWrite(ASYNC, 0, "POST / HTTP/1.1\r\n"),
+ MockWrite(ASYNC, 1, "Transfer-Encoding: chunked\r\n\r\n"),
+ MockWrite(ASYNC, 2, "7\r\nChunk 1\r\n"),
+ MockWrite(SYNCHRONOUS, ERR_FAILED, 3),
+ };
+
+ SequencedSocketData data(nullptr, 0, writes, arraysize(writes));
+ scoped_ptr<ClientSocketHandle> socket_handle =
+ CreateConnectedSocketHandle(&data);
+
+ ChunkedUploadDataStream upload_data_stream(0);
+ ASSERT_EQ(OK, upload_data_stream.Init(TestCompletionCallback().callback()));
+
+ HttpRequestInfo request;
+ request.method = "POST";
+ request.url = GURL("http://localhost");
+ request.upload_data_stream = &upload_data_stream;
+
+ scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
+ HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(),
+ BoundNetLog());
+
+ HttpRequestHeaders headers;
+ headers.SetHeader("Transfer-Encoding", "chunked");
+
+ HttpResponseInfo response;
+ TestCompletionCallback callback;
+ EXPECT_EQ(ERR_IO_PENDING, parser.SendRequest("POST / HTTP/1.1\r\n", headers,
+ &response, callback.callback()));
+
+ base::RunLoop().RunUntilIdle();
+ upload_data_stream.AppendData(kChunk, arraysize(kChunk) - 1, false);
+
+ base::RunLoop().RunUntilIdle();
+ // This write should fail.
+ upload_data_stream.AppendData(kChunk, arraysize(kChunk) - 1, false);
+ EXPECT_EQ(ERR_FAILED, callback.WaitForResult());
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+}
+
// Test to ensure the HttpStreamParser state machine does not get confused
// when sending a request with a chunked body with only one chunk that becomes
// available asynchronously.
@@ -269,6 +473,9 @@ TEST(HttpStreamParser, AsyncSingleChunkAndAsyncSocket) {
parser.ReadResponseBody(body_buffer.get(), kBodySize,
callback.callback()));
ASSERT_EQ(kBodySize, callback.WaitForResult());
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+ EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes());
}
// Test to ensure the HttpStreamParser state machine does not get confused
@@ -336,6 +543,9 @@ TEST(HttpStreamParser, SyncSingleChunkAndAsyncSocket) {
parser.ReadResponseBody(body_buffer.get(), kBodySize,
callback.callback()));
ASSERT_EQ(kBodySize, callback.WaitForResult());
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+ EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes());
}
// Test to ensure the HttpStreamParser state machine does not get confused
@@ -426,6 +636,9 @@ TEST(HttpStreamParser, AsyncChunkAndAsyncSocketWithMultipleChunks) {
parser.ReadResponseBody(body_buffer.get(), kBodySize,
callback.callback()));
ASSERT_EQ(kBodySize, callback.WaitForResult());
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+ EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes());
}
// Test to ensure the HttpStreamParser state machine does not get confused
@@ -493,6 +706,9 @@ TEST(HttpStreamParser, AsyncEmptyChunkedUpload) {
parser.ReadResponseBody(body_buffer.get(), kBodySize,
callback.callback()));
ASSERT_EQ(kBodySize, callback.WaitForResult());
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+ EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes());
}
// Test to ensure the HttpStreamParser state machine does not get confused
@@ -559,6 +775,9 @@ TEST(HttpStreamParser, SyncEmptyChunkedUpload) {
parser.ReadResponseBody(body_buffer.get(), kBodySize,
callback.callback()));
ASSERT_EQ(kBodySize, callback.WaitForResult());
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+ EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes());
}
TEST(HttpStreamParser, TruncatedHeaders) {
@@ -640,16 +859,21 @@ TEST(HttpStreamParser, TruncatedHeaders) {
&response_info, callback.callback()));
int rv = parser.ReadResponseHeaders(callback.callback());
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)),
+ parser.sent_bytes());
if (i == arraysize(reads) - 1) {
EXPECT_EQ(OK, rv);
EXPECT_TRUE(response_info.headers.get());
+ EXPECT_EQ(CountReadBytes(reads[i], 2), parser.received_bytes());
} else {
if (protocol == HTTP) {
EXPECT_EQ(ERR_CONNECTION_CLOSED, rv);
EXPECT_TRUE(response_info.headers.get());
+ EXPECT_EQ(CountReadBytes(reads[i], 2), parser.received_bytes());
} else {
EXPECT_EQ(ERR_RESPONSE_HEADERS_TRUNCATED, rv);
EXPECT_FALSE(response_info.headers.get());
+ EXPECT_EQ(0, parser.received_bytes());
}
}
}
@@ -700,6 +924,11 @@ TEST(HttpStreamParser, Websocket101Response) {
EXPECT_EQ("a fake websocket frame",
base::StringPiece(read_buffer->StartOfBuffer(),
read_buffer->capacity()));
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+ EXPECT_EQ(CountReadBytes(reads, arraysize(reads)) -
+ static_cast<int64_t>(strlen("a fake websocket frame")),
+ parser.received_bytes());
}
// Helper class for constructing HttpStreamParser and running GET requests.
@@ -1017,7 +1246,7 @@ TEST(HttpStreamParser, ReadAfterUnownedObjectsDestroyed) {
const int kBodySize = 1;
MockRead reads[] = {
MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
- MockRead(SYNCHRONOUS, 2, "Content-Length: 1\r\n\r\n"),
+ MockRead(SYNCHRONOUS, 2, "Content-Length: 1\r\n"),
MockRead(SYNCHRONOUS, 3, "Connection: Keep-Alive\r\n\r\n"),
MockRead(SYNCHRONOUS, 4, "1"),
MockRead(SYNCHRONOUS, 0, 5), // EOF
@@ -1051,6 +1280,9 @@ TEST(HttpStreamParser, ReadAfterUnownedObjectsDestroyed) {
scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize));
ASSERT_EQ(kBodySize, parser.ReadResponseBody(
body_buffer.get(), kBodySize, callback.callback()));
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+ EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes());
}
} // namespace
diff --git a/chromium/net/http/http_transaction.h b/chromium/net/http/http_transaction.h
index 6b8ea70cb3b..9ccf3f11cf1 100644
--- a/chromium/net/http/http_transaction.h
+++ b/chromium/net/http/http_transaction.h
@@ -5,6 +5,8 @@
#ifndef NET_HTTP_HTTP_TRANSACTION_H_
#define NET_HTTP_HTTP_TRANSACTION_H_
+#include <stdint.h>
+
#include "net/base/completion_callback.h"
#include "net/base/load_states.h"
#include "net/base/net_export.h"
@@ -122,7 +124,10 @@ class NET_EXPORT_PRIVATE HttpTransaction {
virtual bool GetFullRequestHeaders(HttpRequestHeaders* headers) const = 0;
// Get the number of bytes received from network.
- virtual int64 GetTotalReceivedBytes() const = 0;
+ virtual int64_t GetTotalReceivedBytes() const = 0;
+
+ // Get the number of bytes sent over the network.
+ virtual int64_t GetTotalSentBytes() const = 0;
// Called to tell the transaction that we have successfully reached the end
// of the stream. This is equivalent to performing an extra Read() at the end
@@ -155,6 +160,12 @@ class NET_EXPORT_PRIVATE HttpTransaction {
// provide.
virtual bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const = 0;
+ // Gets the remote endpoint of the socket that the transaction's underlying
+ // stream is using or did use, if any. Returns true and fills in |endpoint|
+ // if it is available; returns false and leaves |endpoint| unchanged if it is
+ // unavailable.
+ virtual bool GetRemoteEndpoint(IPEndPoint* endpoint) const = 0;
+
// Called when the priority of the parent job changes.
virtual void SetPriority(RequestPriority priority) = 0;
diff --git a/chromium/net/http/http_transaction_test_util.cc b/chromium/net/http/http_transaction_test_util.cc
index 1b2960bb250..628c8fa884f 100644
--- a/chromium/net/http/http_transaction_test_util.cc
+++ b/chromium/net/http/http_transaction_test_util.cc
@@ -242,9 +242,9 @@ MockNetworkTransaction::MockNetworkTransaction(RequestPriority priority,
websocket_handshake_stream_create_helper_(NULL),
transaction_factory_(factory->AsWeakPtr()),
received_bytes_(0),
+ sent_bytes_(0),
socket_log_id_(NetLog::Source::kInvalidId),
- weak_factory_(this) {
-}
+ weak_factory_(this) {}
MockNetworkTransaction::~MockNetworkTransaction() {}
@@ -325,10 +325,14 @@ bool MockNetworkTransaction::GetFullRequestHeaders(
return false;
}
-int64 MockNetworkTransaction::GetTotalReceivedBytes() const {
+int64_t MockNetworkTransaction::GetTotalReceivedBytes() const {
return received_bytes_;
}
+int64_t MockNetworkTransaction::GetTotalSentBytes() const {
+ return sent_bytes_;
+}
+
void MockNetworkTransaction::DoneReading() {
if (transaction_factory_.get())
transaction_factory_->TransactionDoneReading();
@@ -374,6 +378,16 @@ bool MockNetworkTransaction::GetLoadTimingInfo(
return true;
}
+bool MockNetworkTransaction::GetRemoteEndpoint(IPEndPoint* endpoint) const {
+ IPAddressNumber number;
+ number.push_back(127);
+ number.push_back(0);
+ number.push_back(0);
+ number.push_back(1);
+ *endpoint = IPEndPoint(number, 80);
+ return true;
+}
+
void MockNetworkTransaction::SetPriority(RequestPriority priority) {
priority_ = priority;
}
@@ -383,6 +397,12 @@ void MockNetworkTransaction::SetWebSocketHandshakeStreamCreateHelper(
websocket_handshake_stream_create_helper_ = create_helper;
}
+// static
+const int64_t MockNetworkTransaction::kTotalReceivedBytes = 1000;
+
+// static
+const int64_t MockNetworkTransaction::kTotalSentBytes = 100;
+
int MockNetworkTransaction::StartInternal(const HttpRequestInfo* request,
const CompletionCallback& callback,
const BoundNetLog& net_log) {
@@ -400,10 +420,12 @@ int MockNetworkTransaction::StartInternal(const HttpRequestInfo* request,
return ERR_IO_PENDING;
}
+ sent_bytes_ = kTotalSentBytes;
+ received_bytes_ = kTotalReceivedBytes;
+
std::string resp_status = t->status;
std::string resp_headers = t->response_headers;
std::string resp_data = t->data;
- received_bytes_ = resp_status.size() + resp_headers.size() + resp_data.size();
if (t->handler)
(t->handler)(request, &resp_status, &resp_headers, &resp_data);
diff --git a/chromium/net/http/http_transaction_test_util.h b/chromium/net/http/http_transaction_test_util.h
index 52b38e845de..61aaeee9b2e 100644
--- a/chromium/net/http/http_transaction_test_util.h
+++ b/chromium/net/http/http_transaction_test_util.h
@@ -7,6 +7,8 @@
#include "net/http/http_transaction.h"
+#include <stdint.h>
+
#include <string>
#include "base/callback.h"
@@ -195,7 +197,9 @@ class MockNetworkTransaction
bool GetFullRequestHeaders(HttpRequestHeaders* headers) const override;
- int64 GetTotalReceivedBytes() const override;
+ int64_t GetTotalReceivedBytes() const override;
+
+ int64_t GetTotalSentBytes() const override;
void DoneReading() override;
@@ -209,6 +213,8 @@ class MockNetworkTransaction
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
+ bool GetRemoteEndpoint(IPEndPoint* endpoint) const override;
+
void SetPriority(RequestPriority priority) override;
void SetWebSocketHandshakeStreamCreateHelper(
@@ -230,6 +236,13 @@ class MockNetworkTransaction
RequestPriority priority() const { return priority_; }
const HttpRequestInfo* request() const { return request_; }
+ // Bogus value that will be returned by GetTotalReceivedBytes() if the
+ // MockNetworkTransaction was started.
+ static const int64_t kTotalReceivedBytes;
+ // Bogus value that will be returned by GetTotalSentBytes() if the
+ // MockNetworkTransaction was started.
+ static const int64_t kTotalSentBytes;
+
private:
int StartInternal(const HttpRequestInfo* request,
const CompletionCallback& callback,
@@ -245,7 +258,8 @@ class MockNetworkTransaction
RequestPriority priority_;
CreateHelper* websocket_handshake_stream_create_helper_;
base::WeakPtr<MockNetworkLayer> transaction_factory_;
- int64 received_bytes_;
+ int64_t received_bytes_;
+ int64_t sent_bytes_;
// NetLog ID of the fake / non-existent underlying socket used by the
// connection. Requires Start() be passed a BoundNetLog with a real NetLog to
diff --git a/chromium/net/http/http_util.cc b/chromium/net/http/http_util.cc
index 53693f4bae5..f1e5143e701 100644
--- a/chromium/net/http/http_util.cc
+++ b/chromium/net/http/http_util.cc
@@ -43,40 +43,6 @@ static size_t FindStringEnd(const std::string& line, size_t start, char delim) {
// HttpUtil -------------------------------------------------------------------
// static
-size_t HttpUtil::FindDelimiter(const std::string& line,
- size_t search_start,
- char delimiter) {
- do {
- // search_start points to the spot from which we should start looking
- // for the delimiter.
- const char delim_str[] = { delimiter, '"', '\'', '\0' };
- size_t cur_delim_pos = line.find_first_of(delim_str, search_start);
- if (cur_delim_pos == std::string::npos)
- return line.length();
-
- char ch = line[cur_delim_pos];
- if (ch == delimiter) {
- // Found delimiter
- return cur_delim_pos;
- }
-
- // We hit the start of a quoted string. Look for its end.
- search_start = FindStringEnd(line, cur_delim_pos, ch);
- if (search_start == line.length())
- return search_start;
-
- ++search_start;
-
- // search_start now points to the first char after the end of the
- // string, so just go back to the top of the loop and look for
- // |delimiter| again.
- } while (true);
-
- NOTREACHED();
- return line.length();
-}
-
-// static
void HttpUtil::ParseContentType(const std::string& content_type_str,
std::string* mime_type,
std::string* charset,
@@ -118,14 +84,15 @@ void HttpUtil::ParseContentType(const std::string& content_type_str,
DCHECK(param_value_begin <= tokenizer.token_end());
TrimLWS(&param_value_begin, &param_value_end);
- if (base::LowerCaseEqualsASCII(param_name_begin, param_name_end,
- "charset")) {
+ if (base::LowerCaseEqualsASCII(
+ base::StringPiece(param_name_begin, param_name_end), "charset")) {
// TODO(abarth): Refactor this function to consistently use iterators.
charset_val = param_value_begin - begin;
charset_end = param_value_end - begin;
type_has_charset = true;
- } else if (base::LowerCaseEqualsASCII(param_name_begin, param_name_end,
- "boundary")) {
+ } else if (base::LowerCaseEqualsASCII(
+ base::StringPiece(param_name_begin, param_name_end),
+ "boundary")) {
if (boundary)
boundary->assign(param_value_begin, param_value_end);
}
@@ -162,16 +129,17 @@ void HttpUtil::ParseContentType(const std::string& content_type_str,
content_type_str.find_first_of('/') != std::string::npos) {
// Common case here is that mime_type is empty
bool eq = !mime_type->empty() &&
- base::LowerCaseEqualsASCII(begin + type_val, begin + type_end,
- mime_type->data());
+ base::LowerCaseEqualsASCII(
+ base::StringPiece(begin + type_val, begin + type_end),
+ mime_type->data());
if (!eq) {
- mime_type->assign(begin + type_val, begin + type_end);
- base::StringToLowerASCII(mime_type);
+ *mime_type = base::ToLowerASCII(
+ base::StringPiece(begin + type_val, begin + type_end));
}
if ((!eq && *had_charset) || type_has_charset) {
*had_charset = true;
- charset->assign(begin + charset_val, begin + charset_end);
- base::StringToLowerASCII(charset);
+ *charset = base::ToLowerASCII(
+ base::StringPiece(begin + charset_val, begin + charset_end));
}
}
}
@@ -220,7 +188,8 @@ bool HttpUtil::ParseRangeHeader(const std::string& ranges_specifier,
TrimLWS(&bytes_unit_begin, &bytes_unit_end);
// "bytes" unit identifier is not found.
- if (!base::LowerCaseEqualsASCII(bytes_unit_begin, bytes_unit_end, "bytes"))
+ if (!base::LowerCaseEqualsASCII(
+ base::StringPiece(bytes_unit_begin, bytes_unit_end), "bytes"))
return false;
ValuesIterator byte_range_set_iterator(byte_range_set_begin,
@@ -352,7 +321,7 @@ const char* const kForbiddenHeaderFields[] = {
// static
bool HttpUtil::IsSafeHeader(const std::string& name) {
- std::string lower_name(base::StringToLowerASCII(name));
+ std::string lower_name(base::ToLowerASCII(name));
if (base::StartsWith(lower_name, "proxy-", base::CompareCase::SENSITIVE) ||
base::StartsWith(lower_name, "sec-", base::CompareCase::SENSITIVE))
return false;
@@ -386,8 +355,9 @@ std::string HttpUtil::StripHeaders(const std::string& headers,
while (it.GetNext()) {
bool should_remove = false;
for (size_t i = 0; i < headers_to_remove_len; ++i) {
- if (base::LowerCaseEqualsASCII(it.name_begin(), it.name_end(),
- headers_to_remove[i])) {
+ if (base::LowerCaseEqualsASCII(
+ base::StringPiece(it.name_begin(), it.name_end()),
+ headers_to_remove[i])) {
should_remove = true;
break;
}
@@ -422,7 +392,7 @@ bool HttpUtil::IsNonCoalescingHeader(std::string::const_iterator name_begin,
"strict-transport-security"
};
for (size_t i = 0; i < arraysize(kNonCoalescingHeaders); ++i) {
- if (base::LowerCaseEqualsASCII(name_begin, name_end,
+ if (base::LowerCaseEqualsASCII(base::StringPiece(name_begin, name_end),
kNonCoalescingHeaders[i]))
return true;
}
@@ -537,7 +507,8 @@ int HttpUtil::LocateStartOfStatusLine(const char* buf, int buf_len) {
if (buf_len >= http_len) {
int i_max = std::min(buf_len - http_len, slop);
for (int i = 0; i <= i_max; ++i) {
- if (base::LowerCaseEqualsASCII(buf + i, buf + i + http_len, "http"))
+ if (base::LowerCaseEqualsASCII(base::StringPiece(buf + i, http_len),
+ "http"))
return i;
}
}
@@ -753,7 +724,7 @@ bool HttpUtil::HasStrongValidators(HttpVersion version,
std::string::const_iterator i = etag_header.begin();
std::string::const_iterator j = etag_header.begin() + slash;
TrimLWS(&i, &j);
- if (!base::LowerCaseEqualsASCII(i, j, "w"))
+ if (!base::LowerCaseEqualsASCII(base::StringPiece(i, j), "w"))
return true;
}
@@ -850,11 +821,12 @@ bool HttpUtil::HeadersIterator::GetNext() {
bool HttpUtil::HeadersIterator::AdvanceTo(const char* name) {
DCHECK(name != NULL);
- DCHECK_EQ(0, base::StringToLowerASCII<std::string>(name).compare(name))
+ DCHECK_EQ(0, base::ToLowerASCII(name).compare(name))
<< "the header name must be in all lower case";
while (GetNext()) {
- if (base::LowerCaseEqualsASCII(name_begin_, name_end_, name)) {
+ if (base::LowerCaseEqualsASCII(base::StringPiece(name_begin_, name_end_),
+ name)) {
return true;
}
}
@@ -889,15 +861,22 @@ bool HttpUtil::ValuesIterator::GetNext() {
HttpUtil::NameValuePairsIterator::NameValuePairsIterator(
std::string::const_iterator begin,
std::string::const_iterator end,
- char delimiter)
+ char delimiter,
+ OptionalValues optional_values)
: props_(begin, end, delimiter),
valid_(true),
name_begin_(end),
name_end_(end),
value_begin_(end),
value_end_(end),
- value_is_quoted_(false) {
-}
+ value_is_quoted_(false),
+ values_optional_(optional_values == VALUES_OPTIONAL) {}
+
+HttpUtil::NameValuePairsIterator::NameValuePairsIterator(
+ std::string::const_iterator begin,
+ std::string::const_iterator end,
+ char delimiter)
+ : NameValuePairsIterator(begin, end, delimiter, VALUES_NOT_OPTIONAL) {}
HttpUtil::NameValuePairsIterator::~NameValuePairsIterator() {}
@@ -907,7 +886,7 @@ HttpUtil::NameValuePairsIterator::~NameValuePairsIterator() {}
// name='\'value\''
// name=value
// name = value
-// name=
+// name (if values_optional_ is true)
// Due to buggy implementations found in some embedded devices, we also
// accept values with missing close quotemark (http://crbug.com/39836):
// name="value
@@ -922,28 +901,34 @@ bool HttpUtil::NameValuePairsIterator::GetNext() {
// Scan for the equals sign.
std::string::const_iterator equals = std::find(value_begin_, value_end_, '=');
- if (equals == value_end_ || equals == value_begin_)
- return valid_ = false; // Malformed, no equals sign
-
- // Verify that the equals sign we found wasn't inside of quote marks.
- for (std::string::const_iterator it = value_begin_; it != equals; ++it) {
- if (HttpUtil::IsQuote(*it))
- return valid_ = false; // Malformed, quote appears before equals sign
+ if (equals == value_begin_)
+ return valid_ = false; // Malformed, no name
+ if (equals == value_end_ && !values_optional_)
+ return valid_ = false; // Malformed, no equals sign and values are required
+
+ // If an equals sign was found, verify that it wasn't inside of quote marks.
+ if (equals != value_end_) {
+ for (std::string::const_iterator it = value_begin_; it != equals; ++it) {
+ if (HttpUtil::IsQuote(*it))
+ return valid_ = false; // Malformed, quote appears before equals sign
+ }
}
name_begin_ = value_begin_;
name_end_ = equals;
- value_begin_ = equals + 1;
+ value_begin_ = (equals == value_end_) ? value_end_ : equals + 1;
TrimLWS(&name_begin_, &name_end_);
TrimLWS(&value_begin_, &value_end_);
value_is_quoted_ = false;
unquoted_value_.clear();
- if (value_begin_ == value_end_)
- return valid_ = false; // Malformed, value is empty
+ if (equals != value_end_ && value_begin_ == value_end_) {
+ // Malformed; value is empty
+ return valid_ = false;
+ }
- if (HttpUtil::IsQuote(*value_begin_)) {
+ if (value_begin_ != value_end_ && HttpUtil::IsQuote(*value_begin_)) {
// Trim surrounding quotemarks off the value
if (*value_begin_ != *(value_end_ - 1) || value_begin_ + 1 == value_end_) {
// NOTE: This is not as graceful as it sounds:
diff --git a/chromium/net/http/http_util.h b/chromium/net/http/http_util.h
index 79a41acd193..1bb3c93f8ab 100644
--- a/chromium/net/http/http_util.h
+++ b/chromium/net/http/http_util.h
@@ -29,14 +29,6 @@ class NET_EXPORT HttpUtil {
// is stripped (username, password, reference).
static std::string SpecForRequest(const GURL& url);
- // Locates the next occurance of delimiter in line, skipping over quoted
- // strings (e.g., commas will not be treated as delimiters if they appear
- // within a quoted string). Returns the offset of the found delimiter or
- // line.size() if no delimiter was found.
- static size_t FindDelimiter(const std::string& line,
- size_t search_start,
- char delimiter);
-
// Parses the value of a Content-Type header. The resulting mime_type and
// charset values are normalized to lowercase. The mime_type and charset
// output values are only modified if the content_type_str contains a mime
@@ -323,9 +315,22 @@ class NET_EXPORT HttpUtil {
// calls to GetNext() or after the NameValuePairsIterator is destroyed.
class NET_EXPORT NameValuePairsIterator {
public:
+ // Whether or not values are optional. VALUES_OPTIONAL allows
+ // e.g. name1=value1;name2;name3=value3, whereas VALUES_NOT_OPTIONAL
+ // will treat it as a parse error because name2 does not have a
+ // corresponding equals sign.
+ enum OptionalValues { VALUES_OPTIONAL, VALUES_NOT_OPTIONAL };
+
+ NameValuePairsIterator(std::string::const_iterator begin,
+ std::string::const_iterator end,
+ char delimiter,
+ OptionalValues optional_values);
+
+ // Treats values as not optional by default (VALUES_NOT_OPTIONAL).
NameValuePairsIterator(std::string::const_iterator begin,
std::string::const_iterator end,
char delimiter);
+
~NameValuePairsIterator();
// Advances the iterator to the next pair, if any. Returns true if there
@@ -353,6 +358,8 @@ class NET_EXPORT HttpUtil {
value_end_);
}
+ bool value_is_quoted() const { return value_is_quoted_; }
+
// The value before unquoting (if any).
std::string raw_value() const { return std::string(value_begin_,
value_end_); }
@@ -373,6 +380,10 @@ class NET_EXPORT HttpUtil {
std::string unquoted_value_;
bool value_is_quoted_;
+
+ // True if values are required for each name/value pair; false if a
+ // name is permitted to appear without a corresponding value.
+ bool values_optional_;
};
};
diff --git a/chromium/net/http/http_util_unittest.cc b/chromium/net/http/http_util_unittest.cc
index 8d0a219573b..a5c984db66b 100644
--- a/chromium/net/http/http_util_unittest.cc
+++ b/chromium/net/http/http_util_unittest.cc
@@ -50,8 +50,7 @@ TEST(HttpUtilTest, IsSafeHeader) {
for (size_t i = 0; i < arraysize(unsafe_headers); ++i) {
EXPECT_FALSE(HttpUtil::IsSafeHeader(unsafe_headers[i]))
<< unsafe_headers[i];
- EXPECT_FALSE(HttpUtil::IsSafeHeader(
- base::StringToUpperASCII(std::string(unsafe_headers[i]))))
+ EXPECT_FALSE(HttpUtil::IsSafeHeader(base::ToUpperASCII(unsafe_headers[i])))
<< unsafe_headers[i];
}
static const char* const safe_headers[] = {
@@ -96,8 +95,7 @@ TEST(HttpUtilTest, IsSafeHeader) {
};
for (size_t i = 0; i < arraysize(safe_headers); ++i) {
EXPECT_TRUE(HttpUtil::IsSafeHeader(safe_headers[i])) << safe_headers[i];
- EXPECT_TRUE(HttpUtil::IsSafeHeader(
- base::StringToUpperASCII(std::string(safe_headers[i]))))
+ EXPECT_TRUE(HttpUtil::IsSafeHeader(base::ToUpperASCII(safe_headers[i])))
<< safe_headers[i];
}
}
@@ -1092,6 +1090,48 @@ TEST(HttpUtilTest, NameValuePairsIterator) {
&parser, false, true, std::string(), std::string()));
}
+TEST(HttpUtilTest, NameValuePairsIteratorOptionalValues) {
+ std::string data = "alpha=1; beta;cappa ; delta; e ; f=1";
+ // Test that the default parser requires values.
+ HttpUtil::NameValuePairsIterator default_parser(data.begin(), data.end(),
+ ';');
+ EXPECT_TRUE(default_parser.valid());
+ ASSERT_NO_FATAL_FAILURE(
+ CheckNextNameValuePair(&default_parser, true, true, "alpha", "1"));
+ ASSERT_NO_FATAL_FAILURE(CheckNextNameValuePair(&default_parser, false, false,
+ std::string(), std::string()));
+
+ HttpUtil::NameValuePairsIterator values_required_parser(
+ data.begin(), data.end(), ';',
+ HttpUtil::NameValuePairsIterator::VALUES_NOT_OPTIONAL);
+ EXPECT_TRUE(values_required_parser.valid());
+ ASSERT_NO_FATAL_FAILURE(CheckNextNameValuePair(&values_required_parser, true,
+ true, "alpha", "1"));
+ ASSERT_NO_FATAL_FAILURE(CheckNextNameValuePair(
+ &values_required_parser, false, false, std::string(), std::string()));
+
+ HttpUtil::NameValuePairsIterator parser(
+ data.begin(), data.end(), ';',
+ HttpUtil::NameValuePairsIterator::VALUES_OPTIONAL);
+ EXPECT_TRUE(parser.valid());
+
+ ASSERT_NO_FATAL_FAILURE(
+ CheckNextNameValuePair(&parser, true, true, "alpha", "1"));
+ ASSERT_NO_FATAL_FAILURE(
+ CheckNextNameValuePair(&parser, true, true, "beta", std::string()));
+ ASSERT_NO_FATAL_FAILURE(
+ CheckNextNameValuePair(&parser, true, true, "cappa", std::string()));
+ ASSERT_NO_FATAL_FAILURE(
+ CheckNextNameValuePair(&parser, true, true, "delta", std::string()));
+ ASSERT_NO_FATAL_FAILURE(
+ CheckNextNameValuePair(&parser, true, true, "e", std::string()));
+ ASSERT_NO_FATAL_FAILURE(
+ CheckNextNameValuePair(&parser, true, true, "f", "1"));
+ ASSERT_NO_FATAL_FAILURE(CheckNextNameValuePair(&parser, false, true,
+ std::string(), std::string()));
+ EXPECT_TRUE(parser.valid());
+}
+
TEST(HttpUtilTest, NameValuePairsIteratorIllegalInputs) {
ASSERT_NO_FATAL_FAILURE(CheckInvalidNameValuePair("alpha=1", "; beta"));
ASSERT_NO_FATAL_FAILURE(CheckInvalidNameValuePair(std::string(), "beta"));
diff --git a/chromium/net/http/mock_http_cache.cc b/chromium/net/http/mock_http_cache.cc
index d89993ccba3..d939a3d8f96 100644
--- a/chromium/net/http/mock_http_cache.cc
+++ b/chromium/net/http/mock_http_cache.cc
@@ -55,9 +55,14 @@ struct MockDiskEntry::CallbackInfo {
};
MockDiskEntry::MockDiskEntry(const std::string& key)
- : key_(key), doomed_(false), sparse_(false),
- fail_requests_(false), fail_sparse_requests_(false), busy_(false),
- delayed_(false) {
+ : key_(key),
+ doomed_(false),
+ sparse_(false),
+ fail_requests_(false),
+ fail_sparse_requests_(false),
+ busy_(false),
+ delayed_(false),
+ cancel_(false) {
test_mode_ = GetTestModeForEntry(key);
}
@@ -148,7 +153,7 @@ int MockDiskEntry::ReadSparseData(int64 offset,
DCHECK(!callback.is_null());
if (fail_sparse_requests_)
return ERR_NOT_IMPLEMENTED;
- if (!sparse_ || busy_)
+ if (!sparse_ || busy_ || cancel_)
return ERR_CACHE_OPERATION_NOT_SUPPORTED;
if (offset < 0)
return ERR_FAILED;
@@ -181,7 +186,7 @@ int MockDiskEntry::WriteSparseData(int64 offset,
DCHECK(!callback.is_null());
if (fail_sparse_requests_)
return ERR_NOT_IMPLEMENTED;
- if (busy_)
+ if (busy_ || cancel_)
return ERR_CACHE_OPERATION_NOT_SUPPORTED;
if (!sparse_) {
if (data_[1].size())
@@ -215,7 +220,7 @@ int MockDiskEntry::GetAvailableRange(int64 offset,
int64* start,
const CompletionCallback& callback) {
DCHECK(!callback.is_null());
- if (!sparse_ || busy_)
+ if (!sparse_ || busy_ || cancel_)
return ERR_CACHE_OPERATION_NOT_SUPPORTED;
if (offset < 0)
return ERR_FAILED;
@@ -345,7 +350,6 @@ void MockDiskEntry::StoreAndDeliverCallbacks(bool store,
}
// Statics.
-bool MockDiskEntry::cancel_ = false;
bool MockDiskEntry::ignore_callbacks_ = false;
//-----------------------------------------------------------------------------
diff --git a/chromium/net/http/mock_http_cache.h b/chromium/net/http/mock_http_cache.h
index c5e5fd9bcf2..632bb3e63c1 100644
--- a/chromium/net/http/mock_http_cache.h
+++ b/chromium/net/http/mock_http_cache.h
@@ -102,7 +102,7 @@ class MockDiskEntry : public disk_cache::Entry,
bool fail_sparse_requests_;
bool busy_;
bool delayed_;
- static bool cancel_;
+ bool cancel_;
static bool ignore_callbacks_;
};
diff --git a/chromium/net/http/proxy_connect_redirect_http_stream.cc b/chromium/net/http/proxy_connect_redirect_http_stream.cc
index 4e12a327229..d0f69fe7cec 100644
--- a/chromium/net/http/proxy_connect_redirect_http_stream.cc
+++ b/chromium/net/http/proxy_connect_redirect_http_stream.cc
@@ -58,10 +58,6 @@ bool ProxyConnectRedirectHttpStream::IsResponseBodyComplete() const {
return true;
}
-bool ProxyConnectRedirectHttpStream::CanFindEndOfResponse() const {
- return true;
-}
-
bool ProxyConnectRedirectHttpStream::IsConnectionReused() const {
NOTREACHED();
return false;
@@ -71,12 +67,15 @@ void ProxyConnectRedirectHttpStream::SetConnectionReused() {
NOTREACHED();
}
-bool ProxyConnectRedirectHttpStream::IsConnectionReusable() const {
- NOTREACHED();
+bool ProxyConnectRedirectHttpStream::CanReuseConnection() const {
return false;
}
-int64 ProxyConnectRedirectHttpStream::GetTotalReceivedBytes() const {
+int64_t ProxyConnectRedirectHttpStream::GetTotalReceivedBytes() const {
+ return 0;
+}
+
+int64_t ProxyConnectRedirectHttpStream::GetTotalSentBytes() const {
return 0;
}
@@ -98,7 +97,7 @@ void ProxyConnectRedirectHttpStream::GetSSLCertRequestInfo(
NOTREACHED();
}
-bool ProxyConnectRedirectHttpStream::IsSpdyHttpStream() const {
+bool ProxyConnectRedirectHttpStream::GetRemoteEndpoint(IPEndPoint* endpoint) {
NOTREACHED();
return false;
}
diff --git a/chromium/net/http/proxy_connect_redirect_http_stream.h b/chromium/net/http/proxy_connect_redirect_http_stream.h
index 701d18d425a..1b0b6d6b163 100644
--- a/chromium/net/http/proxy_connect_redirect_http_stream.h
+++ b/chromium/net/http/proxy_connect_redirect_http_stream.h
@@ -5,6 +5,8 @@
#ifndef NET_HTTP_PROXY_CONNECT_REDIRECT_HTTP_STREAM_H_
#define NET_HTTP_PROXY_CONNECT_REDIRECT_HTTP_STREAM_H_
+#include <stdint.h>
+
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/load_timing_info.h"
@@ -42,21 +44,19 @@ class ProxyConnectRedirectHttpStream : public HttpStream {
bool IsResponseBodyComplete() const override;
- // This function may be called.
- bool CanFindEndOfResponse() const override;
-
bool IsConnectionReused() const override;
void SetConnectionReused() override;
- bool IsConnectionReusable() const override;
+ bool CanReuseConnection() const override;
- int64 GetTotalReceivedBytes() const override;
+ int64_t GetTotalReceivedBytes() const override;
+ int64_t GetTotalSentBytes() const override;
// This function may be called.
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
void GetSSLInfo(SSLInfo* ssl_info) override;
void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override;
- bool IsSpdyHttpStream() const override;
+ bool GetRemoteEndpoint(IPEndPoint* endpoint) override;
void Drain(HttpNetworkSession* session) override;
// This function may be called.
diff --git a/chromium/net/http/transport_security_persister.cc b/chromium/net/http/transport_security_persister.cc
index 74a2e56b1ab..78898c327e5 100644
--- a/chromium/net/http/transport_security_persister.cc
+++ b/chromium/net/http/transport_security_persister.cc
@@ -77,6 +77,7 @@ const char kPinningOnly[] = "pinning-only";
const char kCreated[] = "created";
const char kStsObserved[] = "sts_observed";
const char kPkpObserved[] = "pkp_observed";
+const char kReportUri[] = "report-uri";
std::string LoadState(const base::FilePath& path) {
std::string result;
@@ -188,10 +189,17 @@ bool TransportSecurityPersister::SerializeData(std::string* output) {
serialized->SetDouble(kDynamicSPKIHashesExpiry,
pkp_state.expiry.ToDoubleT());
+ // TODO(svaldez): Historically, both SHA-1 and SHA-256 hashes were
+ // accepted in pins. Per spec, only SHA-256 is accepted now, however
+ // existing serialized pins are still processed. Migrate historical pins
+ // with SHA-1 hashes properly, either by dropping just the bad hashes or
+ // the entire pin. See https://crbug.com/448501.
if (now < pkp_state.expiry) {
serialized->Set(kDynamicSPKIHashes,
SPKIHashesToListValue(pkp_state.spki_hashes));
}
+
+ serialized->SetString(kReportUri, pkp_state.report_uri.spec());
}
base::JSONWriter::WriteWithOptions(
@@ -282,6 +290,13 @@ bool TransportSecurityPersister::Deserialize(const std::string& serialized,
sts_state.expiry = base::Time::FromDoubleT(expiry);
pkp_state.expiry = base::Time::FromDoubleT(dynamic_spki_hashes_expiry);
+ // Don't fail if this key is not present.
+ std::string report_uri_str;
+ parsed->GetString(kReportUri, &report_uri_str);
+ GURL report_uri(report_uri_str);
+ if (report_uri.is_valid())
+ pkp_state.report_uri = report_uri;
+
double sts_observed;
double pkp_observed;
if (parsed->GetDouble(kStsObserved, &sts_observed)) {
diff --git a/chromium/net/http/transport_security_persister_unittest.cc b/chromium/net/http/transport_security_persister_unittest.cc
index 53cb2f4b702..0799f5820bd 100644
--- a/chromium/net/http/transport_security_persister_unittest.cc
+++ b/chromium/net/http/transport_security_persister_unittest.cc
@@ -19,6 +19,8 @@ namespace net {
namespace {
+const char kReportUri[] = "http://www.example.test/report";
+
class TransportSecurityPersisterTest : public testing::Test {
public:
TransportSecurityPersisterTest() {
@@ -86,10 +88,11 @@ TEST_F(TransportSecurityPersisterTest, SerializeData2) {
}
TEST_F(TransportSecurityPersisterTest, SerializeData3) {
+ const GURL report_uri(kReportUri);
// Add an entry.
- HashValue fp1(HASH_VALUE_SHA1);
+ HashValue fp1(HASH_VALUE_SHA256);
memset(fp1.data(), 0, fp1.size());
- HashValue fp2(HASH_VALUE_SHA1);
+ HashValue fp2(HASH_VALUE_SHA256);
memset(fp2.data(), 1, fp2.size());
base::Time expiry =
base::Time::Now() + base::TimeDelta::FromSeconds(1000);
@@ -99,7 +102,7 @@ TEST_F(TransportSecurityPersisterTest, SerializeData3) {
bool include_subdomains = false;
state_.AddHSTS("www.example.com", expiry, include_subdomains);
state_.AddHPKP("www.example.com", expiry, include_subdomains,
- dynamic_spki_hashes);
+ dynamic_spki_hashes, report_uri);
// Add another entry.
memset(fp1.data(), 2, fp1.size());
@@ -110,7 +113,7 @@ TEST_F(TransportSecurityPersisterTest, SerializeData3) {
dynamic_spki_hashes.push_back(fp2);
state_.AddHSTS("www.example.net", expiry, include_subdomains);
state_.AddHPKP("www.example.net", expiry, include_subdomains,
- dynamic_spki_hashes);
+ dynamic_spki_hashes, report_uri);
// Save a copy of everything.
std::set<std::string> sts_saved;
@@ -180,21 +183,23 @@ TEST_F(TransportSecurityPersisterTest, SerializeDataOld) {
EXPECT_TRUE(dirty);
}
-TEST_F(TransportSecurityPersisterTest, PublicKeyHashes) {
+TEST_F(TransportSecurityPersisterTest, PublicKeyPins) {
+ const GURL report_uri(kReportUri);
TransportSecurityState::PKPState pkp_state;
static const char kTestDomain[] = "example.com";
+
EXPECT_FALSE(state_.GetDynamicPKPState(kTestDomain, &pkp_state));
HashValueVector hashes;
std::string failure_log;
EXPECT_FALSE(pkp_state.CheckPublicKeyPins(hashes, &failure_log));
- HashValue sha1(HASH_VALUE_SHA1);
- memset(sha1.data(), '1', sha1.size());
- pkp_state.spki_hashes.push_back(sha1);
+ HashValue sha256(HASH_VALUE_SHA256);
+ memset(sha256.data(), '1', sha256.size());
+ pkp_state.spki_hashes.push_back(sha256);
EXPECT_FALSE(pkp_state.CheckPublicKeyPins(hashes, &failure_log));
- hashes.push_back(sha1);
+ hashes.push_back(sha256);
EXPECT_TRUE(pkp_state.CheckPublicKeyPins(hashes, &failure_log));
hashes[0].data()[0] = '2';
@@ -204,8 +209,8 @@ TEST_F(TransportSecurityPersisterTest, PublicKeyHashes) {
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
bool include_subdomains = false;
state_.AddHSTS(kTestDomain, expiry, include_subdomains);
- state_.AddHPKP(kTestDomain, expiry, include_subdomains,
- pkp_state.spki_hashes);
+ state_.AddHPKP(kTestDomain, expiry, include_subdomains, pkp_state.spki_hashes,
+ report_uri);
std::string serialized;
EXPECT_TRUE(persister_->SerializeData(&serialized));
bool dirty;
@@ -214,9 +219,10 @@ TEST_F(TransportSecurityPersisterTest, PublicKeyHashes) {
TransportSecurityState::PKPState new_pkp_state;
EXPECT_TRUE(state_.GetDynamicPKPState(kTestDomain, &new_pkp_state));
EXPECT_EQ(1u, new_pkp_state.spki_hashes.size());
- EXPECT_EQ(sha1.tag, new_pkp_state.spki_hashes[0].tag);
- EXPECT_EQ(
- 0, memcmp(new_pkp_state.spki_hashes[0].data(), sha1.data(), sha1.size()));
+ EXPECT_EQ(sha256.tag, new_pkp_state.spki_hashes[0].tag);
+ EXPECT_EQ(0, memcmp(new_pkp_state.spki_hashes[0].data(), sha256.data(),
+ sha256.size()));
+ EXPECT_EQ(report_uri, new_pkp_state.report_uri);
}
} // namespace
diff --git a/chromium/net/http/transport_security_state.cc b/chromium/net/http/transport_security_state.cc
index a5f43a016ac..89d467151ba 100644
--- a/chromium/net/http/transport_security_state.cc
+++ b/chromium/net/http/transport_security_state.cc
@@ -19,6 +19,7 @@
#include "base/base64.h"
#include "base/build_time.h"
+#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram_macros.h"
@@ -26,11 +27,13 @@
#include "base/sha1.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/values.h"
#include "crypto/sha2.h"
#include "net/base/dns_util.h"
+#include "net/base/host_port_pair.h"
#include "net/cert/x509_cert_types.h"
#include "net/cert/x509_certificate.h"
#include "net/http/http_security_headers.h"
@@ -47,6 +50,137 @@ namespace {
#include "net/http/transport_security_state_static.h"
+std::string TimeToISO8601(const base::Time& t) {
+ base::Time::Exploded exploded;
+ t.UTCExplode(&exploded);
+ return base::StringPrintf(
+ "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", exploded.year, exploded.month,
+ exploded.day_of_month, exploded.hour, exploded.minute, exploded.second,
+ exploded.millisecond);
+}
+
+scoped_ptr<base::ListValue> GetPEMEncodedChainAsList(
+ const net::X509Certificate* cert_chain) {
+ if (!cert_chain)
+ return make_scoped_ptr(new base::ListValue());
+
+ scoped_ptr<base::ListValue> result(new base::ListValue());
+ std::vector<std::string> pem_encoded_chain;
+ cert_chain->GetPEMEncodedChain(&pem_encoded_chain);
+ for (const std::string& cert : pem_encoded_chain)
+ result->Append(make_scoped_ptr(new base::StringValue(cert)));
+
+ return result.Pass();
+}
+
+bool GetHPKPReport(const HostPortPair& host_port_pair,
+ const TransportSecurityState::PKPState& pkp_state,
+ const X509Certificate* served_certificate_chain,
+ const X509Certificate* validated_certificate_chain,
+ std::string* serialized_report) {
+ // TODO(estark): keep track of reports already sent and rate-limit,
+ // break loops
+ if (pkp_state.report_uri.is_empty())
+ return false;
+
+ base::DictionaryValue report;
+ base::Time now = base::Time::Now();
+ report.SetString("date-time", TimeToISO8601(now));
+ report.SetString("hostname", host_port_pair.host());
+ report.SetInteger("port", host_port_pair.port());
+ report.SetString("effective-expiration-date",
+ TimeToISO8601(pkp_state.expiry));
+ report.SetBoolean("include-subdomains", pkp_state.include_subdomains);
+ report.SetString("noted-hostname", pkp_state.domain);
+
+ scoped_ptr<base::ListValue> served_certificate_chain_list =
+ GetPEMEncodedChainAsList(served_certificate_chain);
+ scoped_ptr<base::ListValue> validated_certificate_chain_list =
+ GetPEMEncodedChainAsList(validated_certificate_chain);
+ report.Set("served-certificate-chain", served_certificate_chain_list.Pass());
+ report.Set("validated-certificate-chain",
+ validated_certificate_chain_list.Pass());
+
+ scoped_ptr<base::ListValue> known_pin_list(new base::ListValue());
+ for (const auto& hash_value : pkp_state.spki_hashes) {
+ std::string known_pin;
+
+ switch (hash_value.tag) {
+ case HASH_VALUE_SHA1:
+ known_pin += "pin-sha1=";
+ break;
+ case HASH_VALUE_SHA256:
+ known_pin += "pin-sha256=";
+ break;
+ }
+
+ std::string base64_value;
+ base::Base64Encode(
+ base::StringPiece(reinterpret_cast<const char*>(hash_value.data()),
+ hash_value.size()),
+ &base64_value);
+ known_pin += "\"" + base64_value + "\"";
+
+ known_pin_list->Append(
+ scoped_ptr<base::Value>(new base::StringValue(known_pin)));
+ }
+
+ report.Set("known-pins", known_pin_list.Pass());
+
+ if (!base::JSONWriter::Write(report, serialized_report)) {
+ LOG(ERROR) << "Failed to serialize HPKP violation report.";
+ return false;
+ }
+
+ return true;
+}
+
+// Do not send a report over HTTPS to the same host that set the
+// pin. Such report URIs will result in loops. (A.com has a pinning
+// violation which results in a report being sent to A.com, which
+// results in a pinning violation which results in a report being sent
+// to A.com, etc.)
+bool IsReportUriValidForHost(const GURL& report_uri, const std::string& host) {
+ return (report_uri.host_piece() != host ||
+ !report_uri.SchemeIsCryptographic());
+}
+
+bool CheckPinsAndMaybeSendReport(
+ const HostPortPair& host_port_pair,
+ const TransportSecurityState::PKPState& pkp_state,
+ const HashValueVector& hashes,
+ const X509Certificate* served_certificate_chain,
+ const X509Certificate* validated_certificate_chain,
+ const TransportSecurityState::PublicKeyPinReportStatus report_status,
+ TransportSecurityState::ReportSender* report_sender,
+ std::string* failure_log) {
+ if (pkp_state.CheckPublicKeyPins(hashes, failure_log))
+ return true;
+
+ if (!report_sender ||
+ report_status != TransportSecurityState::ENABLE_PIN_REPORTS ||
+ pkp_state.report_uri.is_empty()) {
+ return false;
+ }
+
+ DCHECK(pkp_state.report_uri.is_valid());
+ // Report URIs should not be used if they are the same host as the pin
+ // and are HTTPS, to avoid going into a report-sending loop.
+ if (!IsReportUriValidForHost(pkp_state.report_uri, host_port_pair.host()))
+ return false;
+
+ std::string serialized_report;
+
+ if (!GetHPKPReport(host_port_pair, pkp_state, served_certificate_chain,
+ validated_certificate_chain, &serialized_report)) {
+ return false;
+ }
+
+ report_sender->Send(pkp_state.report_uri, serialized_report);
+
+ return false;
+}
+
std::string HashesToBase64String(const HashValueVector& hashes) {
std::string str;
for (size_t i = 0; i != hashes.size(); ++i) {
@@ -313,8 +447,7 @@ bool DecodeHSTSPreloadRaw(const std::string& search_hostname,
// |hostname| has already undergone IDN conversion, so should be
// entirely A-Labels. The preload data is entirely normalized to
// lower case.
- base::StringToLowerASCII(&hostname);
-
+ hostname = base::ToLowerASCII(hostname);
if (hostname.empty()) {
return true;
}
@@ -473,7 +606,7 @@ bool DecodeHSTSPreload(const std::string& hostname, PreloadResult* out) {
} // namespace
TransportSecurityState::TransportSecurityState()
- : delegate_(NULL), enable_static_pins_(true) {
+ : delegate_(nullptr), report_sender_(nullptr), enable_static_pins_(true) {
// Static pinning is only enabled for official builds to make sure that
// others don't end up with pins that cannot be easily updated.
#if !defined(OFFICIAL_BUILD) || defined(OS_ANDROID) || defined(OS_IOS)
@@ -510,24 +643,28 @@ bool TransportSecurityState::ShouldUpgradeToSSL(const std::string& host) {
}
bool TransportSecurityState::CheckPublicKeyPins(
- const std::string& host,
+ const HostPortPair& host_port_pair,
bool is_issued_by_known_root,
const HashValueVector& public_key_hashes,
+ const X509Certificate* served_certificate_chain,
+ const X509Certificate* validated_certificate_chain,
+ const PublicKeyPinReportStatus report_status,
std::string* pinning_failure_log) {
// Perform pin validation if, and only if, all these conditions obtain:
//
// * the server's certificate chain chains up to a known root (i.e. not a
// user-installed trust anchor); and
// * the server actually has public key pins.
- if (!is_issued_by_known_root || !HasPublicKeyPins(host)) {
+ if (!is_issued_by_known_root || !HasPublicKeyPins(host_port_pair.host())) {
return true;
}
- bool pins_are_valid =
- CheckPublicKeyPinsImpl(host, public_key_hashes, pinning_failure_log);
+ bool pins_are_valid = CheckPublicKeyPinsImpl(
+ host_port_pair, public_key_hashes, served_certificate_chain,
+ validated_certificate_chain, report_status, pinning_failure_log);
if (!pins_are_valid) {
LOG(ERROR) << *pinning_failure_log;
- ReportUMAOnPinFailure(host);
+ ReportUMAOnPinFailure(host_port_pair.host());
}
UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", pins_are_valid);
@@ -555,6 +692,12 @@ void TransportSecurityState::SetDelegate(
delegate_ = delegate;
}
+void TransportSecurityState::SetReportSender(
+ TransportSecurityState::ReportSender* report_sender) {
+ DCHECK(CalledOnValidThread());
+ report_sender_ = report_sender;
+}
+
void TransportSecurityState::AddHSTSInternal(
const std::string& host,
TransportSecurityState::STSState::UpgradeMode upgrade_mode,
@@ -575,7 +718,8 @@ void TransportSecurityState::AddHPKPInternal(const std::string& host,
const base::Time& last_observed,
const base::Time& expiry,
bool include_subdomains,
- const HashValueVector& hashes) {
+ const HashValueVector& hashes,
+ const GURL& report_uri) {
DCHECK(CalledOnValidThread());
PKPState pkp_state;
@@ -583,6 +727,7 @@ void TransportSecurityState::AddHPKPInternal(const std::string& host,
pkp_state.expiry = expiry;
pkp_state.include_subdomains = include_subdomains;
pkp_state.spki_hashes = hashes;
+ pkp_state.report_uri = report_uri;
EnablePKPHost(host, pkp_state);
}
@@ -742,14 +887,17 @@ bool TransportSecurityState::AddHPKPHeader(const std::string& host,
base::TimeDelta max_age;
bool include_subdomains;
HashValueVector spki_hashes;
+ GURL report_uri;
+
if (!ParseHPKPHeader(value, ssl_info.public_key_hashes, &max_age,
- &include_subdomains, &spki_hashes)) {
+ &include_subdomains, &spki_hashes, &report_uri)) {
return false;
}
// Handle max-age == 0.
if (max_age.InSeconds() == 0)
spki_hashes.clear();
- AddHPKPInternal(host, now, now + max_age, include_subdomains, spki_hashes);
+ AddHPKPInternal(host, now, now + max_age, include_subdomains, spki_hashes,
+ report_uri);
return true;
}
@@ -763,9 +911,48 @@ void TransportSecurityState::AddHSTS(const std::string& host,
void TransportSecurityState::AddHPKP(const std::string& host,
const base::Time& expiry,
bool include_subdomains,
- const HashValueVector& hashes) {
+ const HashValueVector& hashes,
+ const GURL& report_uri) {
DCHECK(CalledOnValidThread());
- AddHPKPInternal(host, base::Time::Now(), expiry, include_subdomains, hashes);
+ AddHPKPInternal(host, base::Time::Now(), expiry, include_subdomains, hashes,
+ report_uri);
+}
+
+bool TransportSecurityState::ProcessHPKPReportOnlyHeader(
+ const std::string& value,
+ const HostPortPair& host_port_pair,
+ const SSLInfo& ssl_info) {
+ DCHECK(CalledOnValidThread());
+
+ base::Time now = base::Time::Now();
+ bool include_subdomains;
+ HashValueVector spki_hashes;
+ GURL report_uri;
+ std::string unused_failure_log;
+
+ if (!ParseHPKPReportOnlyHeader(value, &include_subdomains, &spki_hashes,
+ &report_uri) ||
+ !report_uri.is_valid() || report_uri.is_empty()) {
+ return false;
+ }
+
+ PKPState pkp_state;
+ pkp_state.last_observed = now;
+ pkp_state.expiry = now;
+ pkp_state.include_subdomains = include_subdomains;
+ pkp_state.spki_hashes = spki_hashes;
+ pkp_state.report_uri = report_uri;
+ pkp_state.domain = DNSDomainToString(CanonicalizeHost(host_port_pair.host()));
+
+ // Only perform pin validation if the cert chains up to a known root.
+ if (!ssl_info.is_issued_by_known_root)
+ return true;
+
+ CheckPinsAndMaybeSendReport(
+ host_port_pair, pkp_state, ssl_info.public_key_hashes,
+ ssl_info.unverified_cert.get(), ssl_info.cert.get(), ENABLE_PIN_REPORTS,
+ report_sender_, &unused_failure_log);
+ return true;
}
// static
@@ -806,21 +993,25 @@ bool TransportSecurityState::IsBuildTimely() {
}
bool TransportSecurityState::CheckPublicKeyPinsImpl(
- const std::string& host,
+ const HostPortPair& host_port_pair,
const HashValueVector& hashes,
+ const X509Certificate* served_certificate_chain,
+ const X509Certificate* validated_certificate_chain,
+ const PublicKeyPinReportStatus report_status,
std::string* failure_log) {
- PKPState dynamic_state;
- if (GetDynamicPKPState(host, &dynamic_state))
- return dynamic_state.CheckPublicKeyPins(hashes, failure_log);
-
- PKPState static_pkp_state;
+ PKPState pkp_state;
STSState unused;
- if (GetStaticDomainState(host, &unused, &static_pkp_state))
- return static_pkp_state.CheckPublicKeyPins(hashes, failure_log);
- // HasPublicKeyPins should have returned true in order for this method
- // to have been called, so if we fall through to here, it's an error.
- return false;
+ if (!GetDynamicPKPState(host_port_pair.host(), &pkp_state) &&
+ !GetStaticDomainState(host_port_pair.host(), &unused, &pkp_state)) {
+ // HasPublicKeyPins should have returned true in order for this method
+ // to have been called, so if we fall through to here, it's an error.
+ return false;
+ }
+
+ return CheckPinsAndMaybeSendReport(
+ host_port_pair, pkp_state, hashes, served_certificate_chain,
+ validated_certificate_chain, report_status, report_sender_, failure_log);
}
bool TransportSecurityState::GetStaticDomainState(const std::string& host,
@@ -856,6 +1047,9 @@ bool TransportSecurityState::GetStaticDomainState(const std::string& host,
return false;
const Pinset *pinset = &kPinsets[result.pinset_id];
+ if (pinset->report_uri != kNoReportURI)
+ pkp_state->report_uri = GURL(pinset->report_uri);
+
if (pinset->accepted_pins) {
const char* const* sha1_hash = pinset->accepted_pins;
while (*sha1_hash) {
diff --git a/chromium/net/http/transport_security_state.h b/chromium/net/http/transport_security_state.h
index b441763cb08..d7befb7cfef 100644
--- a/chromium/net/http/transport_security_state.h
+++ b/chromium/net/http/transport_security_state.h
@@ -5,21 +5,26 @@
#ifndef NET_HTTP_TRANSPORT_SECURITY_STATE_H_
#define NET_HTTP_TRANSPORT_SECURITY_STATE_H_
+#include <stdint.h>
+
#include <map>
#include <string>
#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
#include "base/threading/non_thread_safe.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
#include "net/cert/x509_cert_types.h"
#include "net/cert/x509_certificate.h"
+#include "url/gurl.h"
+
+class GURL;
namespace net {
+class HostPortPair;
class SSLInfo;
// Tracks which hosts have enabled strict transport security and/or public
@@ -45,9 +50,6 @@ class NET_EXPORT TransportSecurityState
virtual ~Delegate() {}
};
- TransportSecurityState();
- ~TransportSecurityState();
-
// A STSState describes the strict transport security state (required
// upgrade to HTTPS).
class NET_EXPORT STSState {
@@ -130,6 +132,10 @@ class NET_EXPORT TransportSecurityState
// Updated by |GetDynamicPKPState| and |GetStaticDomainState|.
std::string domain;
+ // An optional URI indicating where reports should be sent when this
+ // pin is violated, or empty when omitted.
+ GURL report_uri;
+
// Takes a set of SubjectPublicKeyInfo |hashes| and returns true if:
// 1) |bad_static_spki_hashes| does not intersect |hashes|; AND
// 2) Both |static_spki_hashes| and |dynamic_spki_hashes| are empty
@@ -174,15 +180,35 @@ class NET_EXPORT TransportSecurityState
std::map<std::string, PKPState>::const_iterator end_;
};
+ // An interface for asynchronously sending HPKP violation reports.
+ class NET_EXPORT ReportSender {
+ public:
+ // Sends the given serialized |report| to |report_uri|.
+ virtual void Send(const GURL& report_uri, const std::string& report) = 0;
+
+ protected:
+ virtual ~ReportSender() {}
+ };
+
+ // Indicates whether or not a public key pin check should send a
+ // report if a violation is detected.
+ enum PublicKeyPinReportStatus { ENABLE_PIN_REPORTS, DISABLE_PIN_REPORTS };
+
+ TransportSecurityState();
+ ~TransportSecurityState();
+
// These functions search for static and dynamic STS and PKP states, and
- // invoke the
- // functions of the same name on them. These functions are the primary public
- // interface; direct access to STS and PKP states is best left to tests.
+ // invoke the functions of the same name on them. These functions are the
+ // primary public interface; direct access to STS and PKP states is best
+ // left to tests.
bool ShouldSSLErrorsBeFatal(const std::string& host);
bool ShouldUpgradeToSSL(const std::string& host);
- bool CheckPublicKeyPins(const std::string& host,
+ bool CheckPublicKeyPins(const HostPortPair& host_port_pair,
bool is_issued_by_known_root,
const HashValueVector& hashes,
+ const X509Certificate* served_certificate_chain,
+ const X509Certificate* validated_certificate_chain,
+ const PublicKeyPinReportStatus report_status,
std::string* failure_log);
bool HasPublicKeyPins(const std::string& host);
@@ -193,6 +219,8 @@ class NET_EXPORT TransportSecurityState
// TransportSecurityState.
void SetDelegate(Delegate* delegate);
+ void SetReportSender(ReportSender* report_sender);
+
// Clears all dynamic data (e.g. HSTS and HPKP data).
//
// Does NOT persist changes using the Delegate, as this function is only
@@ -268,7 +296,16 @@ class NET_EXPORT TransportSecurityState
void AddHPKP(const std::string& host,
const base::Time& expiry,
bool include_subdomains,
- const HashValueVector& hashes);
+ const HashValueVector& hashes,
+ const GURL& report_uri);
+
+ // Parses |value| as a Public-Key-Pins-Report-Only header value and
+ // sends a HPKP report for |host_port_pair| if |ssl_info| violates the
+ // pin. Returns true if |value| parses and includes a valid
+ // report-uri, and false otherwise.
+ bool ProcessHPKPReportOnlyHeader(const std::string& value,
+ const HostPortPair& host_port_pair,
+ const SSLInfo& ssl_info);
// Returns true iff we have any static public key pins for the |host| and
// iff its set of required pins is the set we expect for Google
@@ -306,9 +343,13 @@ class NET_EXPORT TransportSecurityState
static bool IsBuildTimely();
// Helper method for actually checking pins.
- bool CheckPublicKeyPinsImpl(const std::string& host,
- const HashValueVector& hashes,
- std::string* failure_log);
+ bool CheckPublicKeyPinsImpl(
+ const HostPortPair& host_port_pair,
+ const HashValueVector& hashes,
+ const X509Certificate* served_certificate_chain,
+ const X509Certificate* validated_certificate_chain,
+ const PublicKeyPinReportStatus report_status,
+ std::string* failure_log);
// If a Delegate is present, notify it that the internal state has
// changed.
@@ -325,7 +366,8 @@ class NET_EXPORT TransportSecurityState
const base::Time& last_observed,
const base::Time& expiry,
bool include_subdomains,
- const HashValueVector& hashes);
+ const HashValueVector& hashes,
+ const GURL& report_uri);
// Enable TransportSecurity for |host|. |state| supercedes any previous
// state for the |host|, including static entries.
@@ -344,6 +386,8 @@ class NET_EXPORT TransportSecurityState
Delegate* delegate_;
+ ReportSender* report_sender_;
+
// True if static pins should be used.
bool enable_static_pins_;
diff --git a/chromium/net/http/transport_security_state_static.h b/chromium/net/http/transport_security_state_static.h
index ea645a6653c..6fbfee87a75 100644
--- a/chromium/net/http/transport_security_state_static.h
+++ b/chromium/net/http/transport_security_state_static.h
@@ -269,6 +269,12 @@ enum SecondLevelDomainName {
DOMAIN_GVT3_COM,
DOMAIN_GVT2_COM,
DOMAIN_GOOGLE,
+ DOMAIN_GGPHT_COM,
+ DOMAIN_BLOGSPOT_COM,
+ DOMAIN_DROPBOXSTATIC_COM,
+ DOMAIN_DROPBOXUSERCONTENT_COM,
+ DOMAIN_WITHYOUTUBE_COM,
+ DOMAIN_WITHGOOGLE_COM,
// Boundary value for UMA_HISTOGRAM_ENUMERATION.
DOMAIN_NUM_EVENTS,
};
@@ -536,6 +542,9 @@ static const char* const kNoRejectedPublicKeys[] = {
NULL,
};
+// kNoReportURI is a placeholder for when a pinset does not have a report URI.
+static const char kNoReportURI[] = "";
+
static const char* const kTestAcceptableCerts[] = {
kSPKIHash_TestSPKI,
NULL,
@@ -546,6 +555,7 @@ static const char* const kGoogleAcceptableCerts[] = {
kSPKIHash_GeoTrustGlobal,
NULL,
};
+static const char kGoogleReportURI[] = "http://clients3.google.com/cert_upload_json";
static const char* const kTorAcceptableCerts[] = {
kSPKIHash_RapidSSL,
kSPKIHash_DigiCertEVRoot,
@@ -646,6 +656,7 @@ static const char* const kDropboxAcceptableCerts[] = {
kSPKIHash_ThawtePrimaryRootCA,
NULL,
};
+static const char kDropboxReportURI[] = "https://log.getdropbox.com/hpkp";
static const char* const kFacebookAcceptableCerts[] = {
kSPKIHash_SymantecClass3EVG3,
kSPKIHash_DigiCertECCSecureServerCA,
@@ -664,17 +675,18 @@ static const char* const kSpideroakAcceptableCerts[] = {
struct Pinset {
const char *const *const accepted_pins;
const char *const *const rejected_pins;
+ const char *const report_uri;
};
static const struct Pinset kPinsets[] = {
- {kTestAcceptableCerts, kNoRejectedPublicKeys},
- {kGoogleAcceptableCerts, kNoRejectedPublicKeys},
- {kTorAcceptableCerts, kNoRejectedPublicKeys},
- {kTwitterComAcceptableCerts, kNoRejectedPublicKeys},
- {kTwitterCDNAcceptableCerts, kNoRejectedPublicKeys},
- {kDropboxAcceptableCerts, kNoRejectedPublicKeys},
- {kFacebookAcceptableCerts, kNoRejectedPublicKeys},
- {kSpideroakAcceptableCerts, kNoRejectedPublicKeys},
+ {kTestAcceptableCerts, kNoRejectedPublicKeys, kNoReportURI},
+ {kGoogleAcceptableCerts, kNoRejectedPublicKeys, kGoogleReportURI},
+ {kTorAcceptableCerts, kNoRejectedPublicKeys, kNoReportURI},
+ {kTwitterComAcceptableCerts, kNoRejectedPublicKeys, kNoReportURI},
+ {kTwitterCDNAcceptableCerts, kNoRejectedPublicKeys, kNoReportURI},
+ {kDropboxAcceptableCerts, kNoRejectedPublicKeys, kDropboxReportURI},
+ {kFacebookAcceptableCerts, kNoRejectedPublicKeys, kNoReportURI},
+ {kSpideroakAcceptableCerts, kNoRejectedPublicKeys, kNoReportURI},
};
// kHSTSHuffmanTree describes a Huffman tree. The nodes of the tree are pairs
@@ -683,2250 +695,2789 @@ static const struct Pinset kPinsets[] = {
// value has the MSB set then it represents a literal leaf value. Otherwise
// it's a pointer to the n'th element of the array.
static const uint8 kHSTSHuffmanTree[] = {
- 0xe4, 0xf5, 0x00, 0xf2, 0x01, 0x80, 0xb9, 0xb8, 0x03, 0xb1, 0xb7, 0xb6,
- 0xb5, 0x05, 0xb0, 0x06, 0x04, 0x07, 0x08, 0xea, 0xfa, 0x09, 0xe6, 0x0a,
- 0x0b, 0xed, 0xe9, 0x0c, 0xf7, 0xeb, 0x0e, 0xe3, 0x0f, 0xe1, 0x0d, 0x10,
- 0x02, 0x11, 0xb3, 0xb2, 0xf1, 0xb4, 0x13, 0x14, 0xf8, 0x15, 0xf6, 0x16,
- 0xae, 0x17, 0xe7, 0x18, 0xef, 0x19, 0x1a, 0xff, 0xe2, 0xe8, 0xf3, 0x1c,
- 0xe5, 0x1d, 0xee, 0xec, 0xad, 0xf9, 0x20, 0xf0, 0x21, 0xf4, 0x1f, 0x22,
- 0x1e, 0x23, 0x1b, 0x24, 0x12, 0x25,
+ 0xf5, 0xe4, 0x00, 0xf2, 0x01, 0x80, 0xb2, 0xf1, 0xb9, 0xb6, 0xb8, 0x04,
+ 0xb4, 0x05, 0x03, 0x06, 0xb1, 0xb0, 0xb5, 0xb7, 0x09, 0xb3, 0x08, 0x0a,
+ 0x0b, 0xea, 0x07, 0x0c, 0xe6, 0x0d, 0x0e, 0xed, 0xe9, 0x0f, 0xae, 0xf7,
+ 0x11, 0xe7, 0x12, 0xef, 0x10, 0x13, 0x02, 0x14, 0xeb, 0xe2, 0xe3, 0x16,
+ 0xe1, 0x17, 0x18, 0xff, 0xfa, 0xf8, 0xf6, 0x1a, 0x1b, 0xe8, 0xf3, 0x1c,
+ 0xe5, 0x1d, 0xec, 0xee, 0xad, 0xf9, 0x20, 0xf0, 0xf4, 0x21, 0x1f, 0x22,
+ 0x1e, 0x23, 0x19, 0x24, 0x15, 0x25,
};
static const uint8 kPreloadedHSTSData[] = {
- 0xfe, 0x9b, 0x3b, 0x28, 0x89, 0x1a, 0x22, 0x5b, 0xcd, 0x15, 0x73, 0xae,
- 0xdf, 0xe7, 0x5f, 0xff, 0x3f, 0x1d, 0xa3, 0x0a, 0x6e, 0xd7, 0xcf, 0x9d,
- 0x74, 0x68, 0xea, 0x69, 0xfd, 0x00, 0x5d, 0x13, 0xaf, 0xff, 0x68, 0x2b,
- 0xe0, 0xe6, 0xff, 0x18, 0xe1, 0xd7, 0x66, 0x8e, 0xbd, 0x11, 0x23, 0x44,
- 0x5b, 0x4d, 0x44, 0x2e, 0x24, 0xc8, 0x56, 0xee, 0xe8, 0xea, 0xe9, 0xe2,
- 0xe8, 0xbe, 0xff, 0x98, 0x14, 0xd2, 0x0e, 0xed, 0x3a, 0xf0, 0x13, 0x63,
- 0xa9, 0x0f, 0x52, 0x0e, 0x2f, 0xff, 0x3c, 0xba, 0xea, 0x38, 0xfd, 0x58,
- 0xab, 0x15, 0x64, 0xeb, 0xff, 0xc8, 0x22, 0xfb, 0xf9, 0xce, 0xeb, 0x18,
- 0x3a, 0xec, 0xdc, 0xab, 0x39, 0x56, 0xf7, 0xa6, 0x97, 0xd1, 0x6b, 0xfd,
- 0xfc, 0xef, 0xab, 0x4d, 0x15, 0x31, 0xa9, 0xbf, 0x9b, 0xc4, 0x9d, 0x8c,
- 0x9d, 0x4e, 0x7e, 0x70, 0x89, 0x7f, 0x71, 0x24, 0xeb, 0x43, 0xaf, 0xf3,
- 0xfb, 0xb4, 0x35, 0xd5, 0xce, 0xb0, 0xb9, 0xf0, 0x89, 0x5d, 0xa6, 0x56,
- 0x0b, 0x86, 0x2f, 0x09, 0x8c, 0x87, 0xc7, 0x1d, 0x84, 0x83, 0x4b, 0x53,
- 0xd1, 0x85, 0xf9, 0x84, 0x0d, 0xff, 0xff, 0xd0, 0xb9, 0x93, 0xbd, 0x0f,
- 0x7a, 0xe3, 0x8a, 0x27, 0x39, 0x9e, 0x4e, 0xbf, 0x76, 0x51, 0x12, 0x34,
- 0x54, 0x57, 0xff, 0xe8, 0x68, 0xbe, 0xb3, 0x79, 0x0c, 0x66, 0xf2, 0x3a,
- 0xd3, 0x62, 0x21, 0xa7, 0x19, 0xdf, 0xf8, 0x18, 0xb9, 0xa7, 0xb0, 0x53,
- 0xe7, 0x5f, 0xec, 0xcd, 0x80, 0xf8, 0x03, 0xaf, 0xf3, 0xba, 0x08, 0x85,
- 0x5c, 0xeb, 0xa0, 0x27, 0x5f, 0x71, 0x39, 0x32, 0x87, 0xf1, 0xc3, 0x16,
- 0x0c, 0xaf, 0xdd, 0x94, 0x44, 0x8d, 0x15, 0xed, 0xf9, 0x15, 0x48, 0x3b,
- 0x1d, 0x73, 0xfa, 0x75, 0xa6, 0xc3, 0xf3, 0xe9, 0x9f, 0xa5, 0x57, 0xff,
- 0x4d, 0x0d, 0x9b, 0x3b, 0x28, 0x89, 0x1a, 0x24, 0x6b, 0xff, 0xd3, 0x2e,
- 0x1b, 0x36, 0x76, 0x51, 0x12, 0x34, 0x4f, 0x17, 0xff, 0xa6, 0x5c, 0x36,
- 0x6c, 0xec, 0xa2, 0x24, 0x68, 0x9f, 0xef, 0xff, 0x4c, 0xb8, 0x6c, 0xd9,
- 0xd9, 0x44, 0x48, 0xd1, 0x43, 0x5f, 0xfc, 0xb8, 0x6c, 0xd9, 0xd9, 0x44,
- 0x48, 0xd1, 0x44, 0x5f, 0xf9, 0xb3, 0x07, 0x5e, 0x1f, 0x4e, 0xd3, 0xaa,
- 0x64, 0x48, 0xba, 0x85, 0xff, 0x99, 0x4e, 0x6f, 0x9f, 0x06, 0x2c, 0xeb,
- 0xf7, 0x65, 0x11, 0x23, 0x45, 0x23, 0x7f, 0xce, 0xd7, 0xee, 0xcf, 0xdd,
- 0x8e, 0xbd, 0x0d, 0x9b, 0x0f, 0xb0, 0x4c, 0xef, 0xff, 0xec, 0x07, 0x1f,
- 0xcc, 0xdf, 0x18, 0xf7, 0x5a, 0x7f, 0x4a, 0xb4, 0xce, 0x99, 0xda, 0xe1,
- 0x57, 0x3c, 0x65, 0x7e, 0xec, 0xa2, 0x24, 0x68, 0x94, 0x2f, 0xff, 0x0c,
- 0x7f, 0x5e, 0x44, 0x2d, 0x1c, 0x59, 0xd7, 0xd3, 0x43, 0x66, 0xc3, 0xfc,
- 0x59, 0x9d, 0x6c, 0xcc, 0x10, 0x6c, 0xe3, 0x80, 0x21, 0x31, 0x28, 0x7c,
- 0xa1, 0x5a, 0xbc, 0x2e, 0x3b, 0x0b, 0xc5, 0x9b, 0x71, 0x47, 0xd5, 0x79,
- 0xf9, 0x5f, 0x50, 0xe8, 0x0c, 0x6b, 0xca, 0xa1, 0x77, 0x7f, 0xfa, 0x65,
- 0xc3, 0x66, 0xce, 0xca, 0x22, 0x46, 0x89, 0xce, 0xff, 0xf4, 0xcb, 0x86,
- 0xcd, 0x9d, 0x94, 0x44, 0x8d, 0x14, 0x4d, 0xfc, 0x9a, 0x65, 0xa9, 0xe9,
- 0xd7, 0xf9, 0xf6, 0xf3, 0x3d, 0x03, 0xe9, 0xd7, 0xba, 0xd9, 0xb8, 0x7c,
- 0xde, 0x4b, 0xab, 0xa9, 0xa5, 0xe9, 0x5c, 0x30, 0xbd, 0xbf, 0x76, 0x51,
- 0x12, 0x34, 0x43, 0x97, 0xf0, 0x65, 0xd4, 0x71, 0x3a, 0xd3, 0x61, 0xef,
- 0x70, 0xce, 0xff, 0x9f, 0xb9, 0x2e, 0x3e, 0xed, 0x3a, 0xfa, 0x51, 0x12,
- 0x34, 0x45, 0xf7, 0xec, 0x65, 0xb1, 0xa3, 0xab, 0xa7, 0xa9, 0xe4, 0xb6,
- 0xff, 0x6b, 0x01, 0xcc, 0xf6, 0x0e, 0xb8, 0x76, 0x3a, 0xff, 0xbe, 0x2e,
- 0xbf, 0x20, 0xe3, 0x9d, 0x4e, 0x79, 0xe8, 0x2d, 0x76, 0xb7, 0x3a, 0xfb,
- 0xed, 0x75, 0x0a, 0xa5, 0x9b, 0x98, 0x17, 0xbf, 0x46, 0xdf, 0xce, 0x1d,
- 0x69, 0xb6, 0x4f, 0x47, 0x21, 0x18, 0xc9, 0x27, 0x21, 0x02, 0x2b, 0x33,
- 0xc4, 0x17, 0xff, 0xa6, 0x5c, 0x36, 0x6c, 0xec, 0xa2, 0x24, 0x68, 0x99,
- 0x2f, 0xf4, 0xd9, 0xd9, 0x44, 0x48, 0xd1, 0x6f, 0x5f, 0xfe, 0x99, 0x70,
- 0xd9, 0xb3, 0xb2, 0x88, 0x91, 0xa2, 0x93, 0xb9, 0x5a, 0x9f, 0x0e, 0xbf,
- 0xb7, 0xf7, 0xcf, 0x63, 0xd3, 0xae, 0xe4, 0xd3, 0xe9, 0xe9, 0x41, 0x05,
- 0x3a, 0xbd, 0x76, 0xc7, 0xf3, 0x8d, 0x9a, 0x57, 0x9c, 0x7f, 0xe6, 0x15,
- 0x37, 0xfa, 0x6c, 0xec, 0xa2, 0x24, 0x68, 0x87, 0x6f, 0xdd, 0x94, 0x44,
- 0x8d, 0x12, 0xc5, 0xf6, 0x7a, 0xb4, 0x3a, 0xfd, 0x32, 0xe1, 0xb3, 0x61,
- 0xea, 0x4f, 0x19, 0xdf, 0xe9, 0xb3, 0xb2, 0x88, 0x91, 0xa2, 0x30, 0xbe,
- 0x99, 0xb9, 0xa3, 0xaf, 0xd9, 0xff, 0x5e, 0x47, 0x5f, 0xfe, 0x7f, 0xa7,
- 0xae, 0xd0, 0x71, 0xc6, 0x47, 0x5f, 0xbb, 0x28, 0x89, 0x1a, 0x23, 0xdb,
- 0xed, 0x46, 0xf3, 0x8e, 0xb9, 0xb3, 0x61, 0xeb, 0xfc, 0xce, 0xd3, 0x32,
- 0x8f, 0x4e, 0x93, 0xc4, 0x27, 0xef, 0xdd, 0x94, 0x44, 0x8d, 0x16, 0x1d,
- 0xfe, 0x68, 0xbe, 0x6b, 0x04, 0xeb, 0x4d, 0x87, 0xc5, 0xb9, 0x9d, 0xfe,
- 0x9b, 0x3b, 0x28, 0x89, 0x1a, 0x2e, 0x7a, 0x75, 0x66, 0x3b, 0x42, 0x4d,
- 0xa8, 0x72, 0x3f, 0x48, 0xc5, 0x97, 0x09, 0xef, 0x94, 0xdf, 0xe9, 0xb3,
- 0xb2, 0x88, 0x91, 0xa2, 0x1e, 0xbe, 0x94, 0x44, 0x8d, 0x11, 0x35, 0xfe,
- 0xf8, 0x63, 0x7e, 0x3c, 0xe3, 0xab, 0xa7, 0xc5, 0xf2, 0xdb, 0xff, 0xf3,
- 0xf7, 0xde, 0x3c, 0xe6, 0x5d, 0xd7, 0xac, 0x01, 0xd7, 0xfd, 0xce, 0x3c,
- 0xe6, 0xe7, 0x5c, 0xeb, 0x7f, 0x88, 0x90, 0x85, 0x7b, 0xfe, 0x4f, 0xa7,
- 0xf3, 0xd7, 0xe9, 0xd5, 0x87, 0xbf, 0x05, 0x17, 0xff, 0xf7, 0xf8, 0xfd,
- 0xf7, 0x58, 0x0f, 0x86, 0x25, 0x9d, 0x3a, 0xef, 0xac, 0xeb, 0xff, 0xd9,
- 0xcf, 0x3b, 0x69, 0xd3, 0x7f, 0xba, 0xce, 0xac, 0x45, 0xee, 0xeb, 0x7c,
- 0x16, 0xbe, 0xf8, 0x63, 0xc9, 0xa2, 0x17, 0xbf, 0x81, 0xcc, 0xd8, 0x22,
- 0x75, 0xa6, 0xc5, 0x4f, 0x7c, 0x8c, 0x47, 0x50, 0xdd, 0x09, 0x84, 0xe3,
- 0x0b, 0xfc, 0xfe, 0xea, 0x6f, 0xe8, 0x27, 0x5f, 0x95, 0x9d, 0x26, 0xd3,
- 0xe9, 0xd7, 0x07, 0x87, 0x5f, 0x03, 0x05, 0x93, 0xae, 0x4f, 0x9d, 0x6f,
- 0xa1, 0xb6, 0xe1, 0x0d, 0xfe, 0xdf, 0xfb, 0xb4, 0x22, 0xa1, 0xd7, 0xfe,
- 0x76, 0x47, 0x27, 0x42, 0xd6, 0x87, 0x54, 0x1f, 0xa0, 0x4d, 0xaf, 0xff,
- 0xfe, 0xe0, 0x40, 0x99, 0xd6, 0x47, 0x27, 0x73, 0x00, 0xfa, 0xd3, 0xa8,
- 0x75, 0xff, 0xe4, 0x65, 0xb9, 0xbb, 0x7c, 0x2e, 0x20, 0x4e, 0xba, 0x15,
- 0x1d, 0x69, 0xf7, 0x13, 0x90, 0x52, 0x13, 0x52, 0x21, 0xe3, 0x9c, 0x25,
- 0xdd, 0x3c, 0xa1, 0xd7, 0xee, 0x47, 0xe1, 0xa7, 0x5f, 0xc9, 0xd1, 0xcc,
- 0xe9, 0xd7, 0xf9, 0xba, 0x7d, 0x2b, 0x72, 0xb4, 0xad, 0x1d, 0x7c, 0x9a,
- 0x4f, 0x4e, 0xbc, 0xc3, 0x0c, 0x15, 0x7e, 0x81, 0xff, 0x30, 0xa9, 0x8b,
- 0xfb, 0xf4, 0x7d, 0x9c, 0xf9, 0xd4, 0x04, 0x4e, 0x7a, 0x80, 0x26, 0xb7,
- 0xdc, 0x88, 0x83, 0xaf, 0xfe, 0xf5, 0x19, 0xf1, 0xc7, 0x4e, 0x85, 0x5c,
- 0xeb, 0xf8, 0x43, 0xf4, 0xd9, 0xce, 0xbf, 0xf2, 0x28, 0xe2, 0xfa, 0x74,
- 0x59, 0xd7, 0xf6, 0x4e, 0x0b, 0x73, 0x47, 0x5f, 0x60, 0x33, 0x63, 0xaf,
- 0x95, 0xfc, 0x3a, 0xb2, 0x75, 0xdd, 0x73, 0xab, 0x15, 0x5f, 0xc8, 0x9b,
- 0x72, 0xa4, 0x87, 0x02, 0xb9, 0x83, 0x23, 0xeb, 0x4a, 0xe1, 0x60, 0x9d,
- 0xfc, 0xba, 0x71, 0x0a, 0xa2, 0xbb, 0xfb, 0x18, 0x7c, 0x02, 0x1d, 0x79,
- 0xc3, 0xe9, 0xd7, 0xff, 0xff, 0x84, 0x77, 0x75, 0x07, 0x01, 0xc4, 0x67,
- 0xc6, 0xb3, 0x76, 0xf7, 0x18, 0x3a, 0xfc, 0x9f, 0x0b, 0xec, 0x75, 0xff,
- 0xfe, 0xcd, 0xdb, 0xa5, 0xe0, 0xf8, 0x54, 0x9c, 0xd9, 0x33, 0xa7, 0x5f,
- 0xff, 0xf9, 0x8f, 0x03, 0x92, 0xe2, 0x0e, 0x07, 0x7f, 0xf8, 0x86, 0x31,
- 0x43, 0xaf, 0xf6, 0xed, 0xd2, 0x81, 0x7d, 0xce, 0xbf, 0xd0, 0xc0, 0x59,
- 0x7f, 0xc1, 0xd4, 0xe8, 0xda, 0x47, 0x11, 0x36, 0xbe, 0xf7, 0xe9, 0xb1,
- 0xd7, 0xfb, 0xfc, 0x41, 0xf7, 0xca, 0xce, 0xbf, 0xdb, 0x3a, 0xc5, 0xf7,
- 0xf4, 0xeb, 0x3b, 0x4f, 0xa6, 0x0d, 0x69, 0xd5, 0x5f, 0xe3, 0xda, 0x13,
- 0xf6, 0x33, 0xe8, 0x2d, 0x18, 0x46, 0x5f, 0xff, 0x75, 0x03, 0x3f, 0x3f,
- 0x8d, 0x07, 0xd5, 0xe7, 0xce, 0xb8, 0x2d, 0x3a, 0xfc, 0xfe, 0xeb, 0x6f,
- 0x9d, 0x7a, 0x3f, 0xa3, 0xae, 0x0e, 0xc7, 0x5e, 0x1f, 0xb2, 0xd3, 0x65,
- 0xd1, 0xbb, 0xf8, 0x32, 0xf0, 0x0d, 0xd8, 0x3a, 0x9c, 0xf9, 0x50, 0xce,
- 0xff, 0xfc, 0x17, 0xff, 0x81, 0x0a, 0xaf, 0x19, 0xf9, 0xec, 0xf9, 0xd7,
- 0xff, 0x71, 0xd4, 0xf1, 0xf1, 0x8f, 0xbf, 0xce, 0xbf, 0xde, 0x37, 0x6a,
- 0x70, 0x2b, 0x3a, 0xbd, 0x3f, 0xb1, 0x45, 0xbf, 0xf7, 0x59, 0xf1, 0xa7,
- 0x4d, 0xa3, 0xe7, 0x53, 0x9f, 0x18, 0x48, 0xae, 0x8f, 0x4e, 0xbf, 0xfe,
- 0xf0, 0x2f, 0xa7, 0xd8, 0x70, 0x1c, 0x46, 0x4e, 0xbf, 0xff, 0xfb, 0x5d,
- 0x17, 0x67, 0xc7, 0x9f, 0xa3, 0x73, 0x7f, 0xe4, 0xe1, 0xcd, 0x1d, 0x5d,
- 0x46, 0x38, 0xa8, 0x57, 0xd1, 0xfe, 0x18, 0x6e, 0xd1, 0xd7, 0x32, 0xd3,
- 0xa9, 0xcd, 0x0f, 0x42, 0xaf, 0xfe, 0x1f, 0xea, 0x72, 0x7d, 0xf0, 0x59,
- 0x3a, 0xfd, 0xd4, 0xd3, 0xee, 0x75, 0x61, 0xf5, 0xc2, 0x25, 0xff, 0xa1,
- 0x8e, 0xb8, 0xff, 0x98, 0xa8, 0xea, 0x69, 0xef, 0xf4, 0x82, 0xff, 0xb8,
- 0x9d, 0x67, 0x91, 0x9d, 0x3a, 0xff, 0xff, 0xfe, 0xf7, 0x43, 0x91, 0xbf,
- 0x80, 0x70, 0x3e, 0x07, 0x37, 0x6e, 0x07, 0x61, 0xc8, 0xdc, 0xea, 0x92,
- 0x31, 0x90, 0xe2, 0xf4, 0x44, 0x8d, 0x14, 0xc5, 0x61, 0xe4, 0xc8, 0x8a,
- 0xff, 0xd8, 0x3b, 0xb7, 0x5f, 0x7e, 0xb2, 0x75, 0xec, 0x4f, 0x4e, 0xb6,
- 0x1d, 0x7b, 0x71, 0xcf, 0x4d, 0x54, 0xe1, 0xba, 0x44, 0x4f, 0x43, 0x4d,
- 0xfe, 0xef, 0x23, 0xc2, 0xc0, 0xc9, 0xd7, 0xfb, 0xc6, 0xed, 0x17, 0xcd,
- 0x1d, 0x48, 0x7d, 0x50, 0x6d, 0x7f, 0xfe, 0xf5, 0x35, 0xe3, 0x91, 0xaf,
- 0xbb, 0x3a, 0xe6, 0x1d, 0x7f, 0x27, 0x21, 0x36, 0x73, 0xaf, 0x35, 0xf7,
- 0x3a, 0xff, 0x2c, 0x1c, 0x7d, 0xb1, 0x83, 0xab, 0x0f, 0xef, 0x72, 0xb8,
- 0x1c, 0xbf, 0xff, 0xc3, 0x92, 0xff, 0xdf, 0xfa, 0x64, 0x71, 0x8f, 0x0e,
- 0xac, 0x9d, 0x7f, 0xe9, 0x3a, 0xf9, 0x9a, 0xc4, 0x13, 0xa9, 0xd1, 0x45,
- 0xc6, 0x7b, 0xf7, 0x5e, 0x73, 0xf4, 0xeb, 0xfa, 0x07, 0xc0, 0x1c, 0x4e,
- 0xac, 0x3f, 0x64, 0x22, 0x09, 0x45, 0x3b, 0x26, 0xf3, 0x65, 0x76, 0x8b,
- 0x02, 0x18, 0x0a, 0x10, 0x4a, 0x33, 0xbd, 0xe3, 0x20, 0x44, 0x96, 0x61,
- 0xd5, 0xd8, 0xcc, 0x57, 0x0b, 0xfe, 0x42, 0x2f, 0xd2, 0x01, 0x86, 0x9f,
- 0xe3, 0x46, 0xbf, 0xee, 0xc3, 0x1e, 0x20, 0x11, 0xb1, 0xd7, 0xff, 0xfc,
- 0xe0, 0xcd, 0xa0, 0x7f, 0xa7, 0x97, 0x85, 0xad, 0x06, 0x47, 0x5f, 0xf3,
- 0xb3, 0xc4, 0x75, 0xc0, 0x0e, 0xa5, 0x11, 0xb0, 0x27, 0x61, 0x66, 0xbe,
- 0xc1, 0x51, 0x5c, 0xeb, 0xff, 0xff, 0xf7, 0x13, 0xfc, 0xce, 0xbc, 0xef,
- 0x0b, 0x0a, 0xaf, 0x19, 0xbb, 0x70, 0x23, 0xee, 0x8e, 0xb7, 0xd1, 0x16,
- 0x1a, 0x24, 0xbf, 0xf3, 0xcb, 0xc0, 0xc6, 0x96, 0xe2, 0x75, 0xff, 0xfb,
- 0x33, 0x89, 0x2e, 0x67, 0x8d, 0x07, 0x8e, 0xae, 0x75, 0xff, 0xf7, 0xf9,
- 0x9e, 0xf8, 0x5b, 0xe7, 0xc1, 0x82, 0x75, 0xff, 0x6f, 0xe1, 0x6f, 0x83,
- 0xf9, 0xe3, 0xad, 0xac, 0x44, 0x6c, 0x28, 0x52, 0xd3, 0x49, 0x13, 0xdf,
- 0xc3, 0x96, 0xff, 0xff, 0xfc, 0x39, 0xbb, 0x53, 0x43, 0x93, 0xb9, 0x8c,
- 0xf1, 0xc5, 0x9f, 0x11, 0x24, 0x9c, 0x75, 0x22, 0x2f, 0x02, 0x6b, 0x7d,
- 0xdd, 0x9a, 0xd3, 0xaf, 0xcd, 0x7d, 0xdb, 0xa3, 0xaf, 0xff, 0xff, 0xfd,
- 0x82, 0xa7, 0x84, 0xe0, 0x66, 0x65, 0x3e, 0xeb, 0x18, 0x53, 0x89, 0x36,
- 0x73, 0x7f, 0x5c, 0x05, 0x5f, 0xff, 0xfd, 0x24, 0x60, 0x01, 0xef, 0x80,
- 0xbe, 0xda, 0x97, 0x03, 0xcd, 0xe1, 0x83, 0xae, 0x0e, 0xdb, 0xa6, 0x80,
- 0x85, 0x1a, 0x84, 0xfd, 0x3a, 0xbf, 0x5e, 0x4a, 0x2d, 0x82, 0x21, 0x8d,
- 0x8e, 0xff, 0x43, 0x71, 0x70, 0x3e, 0x9d, 0x7d, 0x9c, 0x76, 0x4e, 0xbc,
- 0xb9, 0x78, 0xe1, 0xe9, 0x41, 0x8d, 0xff, 0xff, 0xf6, 0x76, 0x43, 0x93,
- 0xbc, 0x69, 0x30, 0x7d, 0xf0, 0x39, 0x38, 0x73, 0x53, 0x8e, 0xbf, 0xff,
- 0x20, 0xff, 0x98, 0xab, 0xec, 0xe2, 0xbc, 0x0f, 0xa7, 0x5f, 0x9d, 0x8f,
- 0x1a, 0x64, 0xeb, 0xff, 0x0e, 0xc3, 0x93, 0xb4, 0x17, 0xdc, 0xeb, 0xff,
- 0x03, 0x8f, 0xbf, 0x85, 0x6f, 0x9d, 0xea, 0x1d, 0x4e, 0x88, 0xbd, 0x90,
- 0x29, 0x13, 0xb5, 0xd4, 0x20, 0xfe, 0xb2, 0x18, 0x5b, 0x5f, 0x67, 0xf2,
- 0x7e, 0x3a, 0xf4, 0xf6, 0x70, 0xeb, 0xb0, 0x07, 0x56, 0xca, 0xa2, 0x5b,
- 0x1f, 0x56, 0x91, 0xfe, 0x4b, 0x38, 0x7a, 0xfc, 0x9f, 0xd6, 0x7a, 0x75,
- 0xfc, 0x07, 0x1e, 0x43, 0x4e, 0xbc, 0xe0, 0x73, 0xaf, 0xd9, 0xfd, 0x43,
- 0x3e, 0x0f, 0x15, 0x65, 0x77, 0xf3, 0x1e, 0x27, 0xc5, 0x6e, 0x9f, 0xe7,
- 0xc3, 0xa9, 0xa8, 0x88, 0x44, 0x1b, 0xff, 0xf7, 0x43, 0xde, 0xb8, 0xe2,
- 0x89, 0xce, 0x67, 0x93, 0xaf, 0x83, 0x1b, 0xfc, 0xea, 0x6a, 0x71, 0xcc,
- 0xc3, 0xd3, 0xa4, 0x5c, 0x56, 0xa3, 0xaf, 0xed, 0x4a, 0x50, 0x2a, 0x1d,
- 0x4a, 0xc4, 0xdb, 0xfc, 0x2a, 0xff, 0x0f, 0x89, 0xdb, 0xb7, 0x4c, 0x9d,
- 0x76, 0xdb, 0x9d, 0x7e, 0xe4, 0x2b, 0xbf, 0xa7, 0x50, 0x0f, 0xee, 0x0e,
- 0x55, 0x0c, 0x5f, 0xee, 0xb2, 0x39, 0xc8, 0xf9, 0xd4, 0xe9, 0x82, 0x64,
- 0x28, 0x90, 0xc2, 0xfc, 0x9d, 0x06, 0x09, 0xd7, 0xef, 0x73, 0xfe, 0x76,
- 0x3a, 0xff, 0x31, 0xfc, 0xe7, 0x8d, 0xf4, 0x75, 0x39, 0xf1, 0x41, 0x5d,
- 0x35, 0x1b, 0x5c, 0x33, 0x18, 0x43, 0xdf, 0xf7, 0xf9, 0x8d, 0x81, 0xcd,
- 0xce, 0xbf, 0xff, 0xe1, 0x8f, 0x75, 0xb6, 0x20, 0xfc, 0x72, 0x77, 0x8d,
- 0x30, 0x27, 0x50, 0xa2, 0x83, 0xe6, 0xf7, 0xfe, 0x4c, 0x67, 0xc6, 0x9f,
- 0x90, 0xae, 0x75, 0xff, 0x6f, 0x8f, 0xbb, 0x22, 0xeb, 0x3a, 0xfe, 0xdf,
- 0x5c, 0xc8, 0xe9, 0xd7, 0xff, 0xfe, 0x45, 0xf5, 0x33, 0x71, 0x0f, 0xdf,
- 0x9e, 0x27, 0x27, 0xd9, 0x73, 0xaa, 0x11, 0x39, 0xf2, 0xda, 0x02, 0x67,
- 0x3c, 0x42, 0xfc, 0x35, 0x6f, 0xfb, 0x3b, 0xb3, 0xa7, 0x70, 0x4e, 0xb2,
- 0xce, 0xf0, 0x6d, 0xaf, 0x0e, 0x00, 0xea, 0x73, 0x79, 0xb9, 0x15, 0xfd,
- 0xbe, 0xb3, 0x05, 0x43, 0xaf, 0x97, 0xe5, 0xfd, 0x3a, 0xb0, 0xf4, 0x50,
- 0xb6, 0xff, 0x47, 0xf9, 0x0c, 0xf9, 0x59, 0xd7, 0x83, 0xbf, 0xa7, 0x53,
- 0xaa, 0xe8, 0xc8, 0xd6, 0xd2, 0x15, 0x1d, 0x72, 0x82, 0x01, 0x35, 0xbf,
- 0xdf, 0x4d, 0xb3, 0x81, 0xf9, 0xd6, 0x64, 0xeb, 0xfb, 0x03, 0x9c, 0x96,
- 0xc7, 0x5d, 0x9b, 0xb9, 0xbe, 0xd0, 0x8d, 0xfd, 0xc8, 0x6a, 0xfa, 0x87,
- 0x5f, 0xfe, 0x75, 0x14, 0x8f, 0xeb, 0xe2, 0xfb, 0xb4, 0xeb, 0x93, 0x47,
- 0x5e, 0xee, 0x6e, 0x75, 0x00, 0xd8, 0xfa, 0x2b, 0x7e, 0x4d, 0x69, 0xd6,
- 0x75, 0x21, 0xe4, 0x4e, 0x22, 0xa5, 0x13, 0xb0, 0x47, 0x1f, 0x4b, 0x04,
- 0xb0, 0x30, 0xc4, 0xbf, 0x01, 0x06, 0x00, 0x75, 0xff, 0xf9, 0xbc, 0xc6,
- 0x78, 0xe2, 0xa0, 0xe7, 0xf8, 0x13, 0xa9, 0x0f, 0xeb, 0xa4, 0xb7, 0xff,
- 0xf9, 0x33, 0x76, 0xeb, 0xfc, 0x75, 0xba, 0x03, 0xc3, 0xab, 0x27, 0x5f,
- 0xe8, 0x1f, 0x12, 0xd7, 0xa0, 0x3a, 0xff, 0xc1, 0xd7, 0x85, 0xf9, 0xe4,
- 0x71, 0xce, 0xbf, 0x67, 0xc3, 0x9b, 0x9d, 0x79, 0x4c, 0xdc, 0xeb, 0x9d,
- 0x9f, 0x07, 0x89, 0xf2, 0x7a, 0x14, 0x5b, 0x06, 0x10, 0xd7, 0xff, 0xff,
- 0xe0, 0x8f, 0x86, 0x23, 0x76, 0xf6, 0x3d, 0xf1, 0xa0, 0xbe, 0xfc, 0xc4,
- 0x1c, 0x50, 0xeb, 0xff, 0xf0, 0x7b, 0xdc, 0xfe, 0xb8, 0x99, 0xe3, 0x9e,
- 0xb9, 0xd5, 0x88, 0xe0, 0xe4, 0x22, 0x6f, 0xd8, 0x32, 0xf2, 0xb3, 0xaf,
- 0xfe, 0xe6, 0x38, 0xb2, 0x39, 0xfd, 0x41, 0xd6, 0x6f, 0xcf, 0xa5, 0x51,
- 0x45, 0xff, 0xf8, 0x18, 0xbf, 0x0a, 0xbe, 0xfa, 0x65, 0xb1, 0xdd, 0x8e,
- 0xbf, 0xff, 0xbe, 0x9b, 0x60, 0x3c, 0x2e, 0x1b, 0xd4, 0xda, 0x16, 0x75,
- 0xfe, 0xda, 0x16, 0x2f, 0xd6, 0x4e, 0xbf, 0xed, 0xf1, 0x4f, 0x57, 0x9e,
- 0x3b, 0x88, 0x90, 0x45, 0xdb, 0xfe, 0xc1, 0xdb, 0xc7, 0xb1, 0x0c, 0x9d,
- 0x7f, 0xdd, 0xd9, 0xf6, 0xd8, 0x3d, 0xd8, 0xeb, 0xff, 0x78, 0x67, 0x81,
- 0x51, 0x30, 0x54, 0x3a, 0xff, 0x0f, 0x8d, 0x06, 0x78, 0x3d, 0x3a, 0xb0,
- 0xfe, 0x82, 0x85, 0x4e, 0x8d, 0x8d, 0x42, 0xde, 0xff, 0xf6, 0xde, 0x35,
- 0xc0, 0xf8, 0xfe, 0xb4, 0xfd, 0x3a, 0xff, 0xff, 0xd9, 0xbe, 0x93, 0x18,
- 0xf1, 0xcc, 0xfe, 0xb3, 0x6f, 0x18, 0x80, 0x3a, 0xb1, 0x18, 0x08, 0xa1,
- 0x5b, 0x2f, 0x36, 0x01, 0x99, 0x48, 0x75, 0xca, 0x30, 0x7d, 0xe1, 0x20,
- 0x85, 0x5d, 0x87, 0x5a, 0xd5, 0x35, 0x18, 0x9f, 0xe1, 0xcf, 0x7f, 0xbe,
- 0x39, 0xfe, 0x66, 0xc7, 0x5f, 0xfa, 0x3b, 0xcc, 0xfb, 0x8a, 0x7a, 0x75,
- 0xff, 0xf0, 0xe6, 0xde, 0x3d, 0x0f, 0xf3, 0x17, 0xeb, 0x07, 0x5f, 0x37,
- 0xe9, 0xb1, 0xd7, 0xfd, 0x8c, 0x6e, 0xdd, 0x78, 0xfa, 0x1d, 0x7f, 0xfc,
- 0xcf, 0x10, 0x41, 0xe3, 0xcc, 0x87, 0x39, 0x87, 0x5f, 0xf7, 0x11, 0x6f,
- 0x83, 0xfd, 0x1d, 0x7f, 0xff, 0x83, 0xfe, 0x85, 0x9f, 0x1f, 0x67, 0x81,
- 0xf7, 0xe9, 0x8a, 0x8e, 0xbe, 0x79, 0x3a, 0xfc, 0x23, 0xc6, 0x4a, 0x42,
- 0x6d, 0x4e, 0xa9, 0x62, 0x46, 0x5d, 0x3c, 0x85, 0x41, 0x22, 0x55, 0x19,
- 0x6d, 0xf2, 0x7d, 0x1c, 0xeb, 0xff, 0xff, 0xc2, 0x8a, 0x72, 0x19, 0xf0,
- 0x21, 0x55, 0xe3, 0x37, 0x6e, 0x04, 0x7d, 0xd1, 0xd7, 0xee, 0x23, 0x8e,
- 0xc7, 0x5d, 0xf7, 0x5a, 0x29, 0x67, 0x3f, 0xd3, 0x51, 0xe8, 0x90, 0xc4,
- 0xa7, 0x65, 0x87, 0x64, 0xf4, 0x6a, 0x4b, 0x08, 0x88, 0xd4, 0xaf, 0xce,
- 0x3f, 0x49, 0xc7, 0x5f, 0x7f, 0x51, 0xe9, 0xd7, 0xff, 0x71, 0x3c, 0x27,
- 0x43, 0xb4, 0x76, 0x47, 0x5f, 0x27, 0x23, 0x63, 0xaf, 0xa7, 0x3f, 0xdc,
- 0xeb, 0xf6, 0xb3, 0xe9, 0xa3, 0xaf, 0xc1, 0x9f, 0x86, 0x3e, 0x75, 0xfd,
- 0xc8, 0xdb, 0xc3, 0x7e, 0x75, 0xfb, 0xc8, 0xb5, 0xab, 0x3a, 0xfd, 0x1d,
- 0x1d, 0xd0, 0xea, 0x74, 0x55, 0x21, 0x5f, 0xa6, 0x1f, 0x29, 0xa0, 0x27,
- 0xbd, 0x84, 0xea, 0x11, 0x49, 0x19, 0x08, 0x59, 0x22, 0xfc, 0x34, 0x2f,
- 0xf7, 0x1d, 0x06, 0x3a, 0xa1, 0xd7, 0xf3, 0xa0, 0xc7, 0x54, 0x3a, 0xff,
- 0x7b, 0x1e, 0xf7, 0xa9, 0xdf, 0x07, 0xb9, 0xc3, 0x1b, 0x7a, 0x75, 0xfc,
- 0xfd, 0xd9, 0xfb, 0xb1, 0xd7, 0x83, 0x1a, 0x3a, 0x9a, 0x79, 0x3e, 0x4b,
- 0xaf, 0xff, 0xe4, 0xef, 0x8c, 0x4c, 0x15, 0x38, 0x98, 0xbc, 0x91, 0xd7,
- 0xff, 0xfc, 0x9b, 0x75, 0xd7, 0xa0, 0xbf, 0x87, 0xeb, 0x83, 0x8e, 0xb3,
- 0xab, 0x11, 0x81, 0xd5, 0x9b, 0xff, 0x77, 0x37, 0xe6, 0xee, 0xbd, 0x9c,
- 0xeb, 0xff, 0xff, 0xdd, 0xea, 0x6d, 0xe3, 0x99, 0xf1, 0x76, 0x79, 0x9b,
- 0x3e, 0xff, 0x0c, 0x8e, 0xbf, 0xff, 0xf9, 0xd4, 0xe3, 0xf8, 0x1c, 0x0a,
- 0x9e, 0x37, 0x6e, 0x90, 0x7c, 0xbe, 0xc7, 0x5f, 0xb7, 0xd2, 0x60, 0x9d,
- 0x58, 0x89, 0xf0, 0xbc, 0xd2, 0x26, 0x7b, 0xc8, 0xc6, 0xef, 0xfe, 0x6e,
- 0x91, 0x4e, 0x3a, 0x6c, 0xea, 0x1d, 0x7f, 0xc2, 0x16, 0x47, 0x39, 0x1f,
- 0x3a, 0xff, 0x71, 0xd8, 0x07, 0x21, 0x67, 0x5f, 0xf2, 0xf3, 0x5e, 0x19,
- 0x17, 0x59, 0xd4, 0x03, 0xed, 0x59, 0x9d, 0xff, 0xff, 0x47, 0x79, 0x9f,
- 0x4c, 0x1d, 0xb4, 0xf8, 0x20, 0xe3, 0x9d, 0x7d, 0xff, 0x1b, 0x74, 0xea,
- 0xdd, 0x10, 0xf0, 0xc5, 0x7f, 0xff, 0xed, 0xf3, 0x60, 0xaa, 0xf1, 0xbb,
- 0x7e, 0xec, 0x78, 0xce, 0xfb, 0xeb, 0x9d, 0x7f, 0xf9, 0x88, 0x1d, 0x96,
- 0x14, 0x02, 0x0a, 0x1d, 0x7f, 0x33, 0xbb, 0x42, 0xff, 0x3a, 0xff, 0xb9,
- 0x0b, 0x1c, 0xe4, 0x7c, 0xeb, 0xec, 0xef, 0xac, 0x1d, 0x4e, 0x88, 0x8d,
- 0x17, 0xfc, 0xda, 0xfe, 0xcf, 0xf7, 0xb8, 0xd3, 0xaf, 0xe1, 0xce, 0x0e,
- 0x48, 0xeb, 0xe1, 0xcd, 0x78, 0x64, 0xf5, 0xbe, 0x59, 0x7f, 0xd8, 0xbe,
- 0x3a, 0x74, 0x2a, 0xe7, 0x50, 0x17, 0x6f, 0xd4, 0x22, 0x94, 0x6f, 0xbb,
- 0x94, 0xa2, 0x2f, 0x61, 0x49, 0xc8, 0x54, 0xc1, 0x1e, 0x9e, 0x3f, 0x0d,
- 0x09, 0xd0, 0x85, 0xf2, 0x77, 0x7f, 0xec, 0x60, 0x70, 0x38, 0xa3, 0x7d,
- 0x3a, 0xff, 0xc3, 0x9e, 0x3b, 0x9c, 0x1c, 0x64, 0xeb, 0xff, 0xfd, 0xc8,
- 0xf7, 0x5e, 0x07, 0x27, 0x0e, 0x6b, 0x16, 0xf2, 0x3a, 0x85, 0x14, 0x1a,
- 0x3e, 0xa5, 0x62, 0xc8, 0xc4, 0x75, 0xac, 0x9e, 0xa3, 0xde, 0x18, 0xd1,
- 0x0d, 0xfb, 0xfb, 0x98, 0x3f, 0xf4, 0x27, 0x5f, 0x85, 0xd7, 0x00, 0x3a,
- 0xff, 0x63, 0x3c, 0xcf, 0xb8, 0x0e, 0xbf, 0x87, 0xf0, 0xb4, 0xf9, 0xd6,
- 0x69, 0xd4, 0xe6, 0xef, 0xe5, 0x77, 0x86, 0x4e, 0x75, 0xff, 0xff, 0xf7,
- 0x33, 0xfa, 0x86, 0x7c, 0x0e, 0x6e, 0xdc, 0x0e, 0xc3, 0x80, 0xe2, 0x32,
- 0x75, 0xc1, 0x50, 0xea, 0x44, 0x58, 0xf4, 0x6b, 0xf0, 0x80, 0xbf, 0xb3,
- 0x61, 0xcd, 0xf4, 0x75, 0xff, 0xff, 0xf9, 0xba, 0xd0, 0x5f, 0xe8, 0x0c,
- 0x16, 0x7c, 0x0e, 0x75, 0xc7, 0xfc, 0xc5, 0x47, 0x5f, 0xfd, 0xbb, 0x75,
- 0x8b, 0xdd, 0xf9, 0xc7, 0x3a, 0xb7, 0x46, 0x4f, 0x61, 0x09, 0x6d, 0x1d,
- 0x41, 0x37, 0x3e, 0x4a, 0x6f, 0xec, 0xdd, 0xaf, 0xeb, 0x9d, 0x7e, 0x1c,
- 0xe4, 0x7c, 0xeb, 0x3e, 0xe7, 0xa4, 0xb2, 0xdb, 0xef, 0x12, 0xd9, 0x83,
- 0xaf, 0xdb, 0x78, 0x0b, 0xb2, 0x75, 0xff, 0xff, 0x0b, 0xfb, 0xbb, 0x74,
- 0x17, 0xf8, 0xe0, 0x13, 0x3a, 0xc9, 0xd5, 0x08, 0x91, 0xf9, 0x5d, 0x01,
- 0x71, 0xa5, 0x0b, 0x59, 0x25, 0xe3, 0x6c, 0x43, 0x44, 0x4d, 0x35, 0x19,
- 0x78, 0x5d, 0x67, 0x14, 0x79, 0x85, 0xbd, 0xf9, 0xa9, 0xdc, 0xdc, 0xeb,
- 0xda, 0xe6, 0x1d, 0x7e, 0xcd, 0x6d, 0x8c, 0x1d, 0x5b, 0x9f, 0x53, 0x24,
- 0xfc, 0x1b, 0xbf, 0xff, 0x26, 0xd9, 0x20, 0x71, 0x31, 0x4f, 0x0a, 0x05,
- 0xce, 0xbf, 0xfc, 0xfb, 0xb7, 0x5f, 0x8d, 0x95, 0x0e, 0x6e, 0x75, 0xff,
- 0xcd, 0x7e, 0x6c, 0x98, 0x3b, 0xb7, 0x47, 0x5f, 0x2a, 0xfe, 0x70, 0xeb,
- 0x91, 0x67, 0x5f, 0xff, 0xfb, 0x76, 0xc6, 0xfe, 0x04, 0x2a, 0xbc, 0x66,
- 0xed, 0xc0, 0x8f, 0xba, 0x3a, 0x96, 0x88, 0xa5, 0x42, 0xb7, 0xa7, 0x92,
- 0x7e, 0x3a, 0xb6, 0x47, 0xae, 0x42, 0xb6, 0x78, 0x96, 0xff, 0xff, 0xfc,
- 0xfb, 0xe8, 0x2f, 0xbf, 0x8e, 0x60, 0x3c, 0x0e, 0x05, 0x4f, 0x1a, 0xf7,
- 0xd4, 0xf9, 0xd7, 0xe7, 0x1d, 0xe3, 0x63, 0xaf, 0xff, 0xff, 0xfe, 0x5e,
- 0x49, 0xf8, 0xeb, 0xfe, 0x6b, 0x4f, 0xde, 0xb8, 0xe6, 0xd8, 0x1d, 0x05,
- 0x91, 0x75, 0x9d, 0x7e, 0x8f, 0x7c, 0xc6, 0xc7, 0x56, 0x23, 0x1d, 0x21,
- 0x3b, 0x79, 0x3d, 0x73, 0xaf, 0xe0, 0x0e, 0x72, 0x3e, 0x75, 0xfb, 0xfb,
- 0xb5, 0x3a, 0x75, 0x61, 0xe9, 0xe8, 0xae, 0xb6, 0x44, 0x7f, 0xad, 0xd7,
- 0xfb, 0x60, 0xbf, 0xd6, 0x9f, 0x3a, 0xff, 0xce, 0xa2, 0xa0, 0xe0, 0xb3,
- 0xe5, 0x67, 0x56, 0x1f, 0xb6, 0xe6, 0x77, 0xfe, 0xcc, 0xf7, 0x5e, 0x3b,
- 0xa0, 0x68, 0xeb, 0xfd, 0xdc, 0x97, 0x13, 0xac, 0x9d, 0x76, 0x7c, 0x07,
- 0xe9, 0x88, 0x37, 0xdb, 0x20, 0xfc, 0xeb, 0xf6, 0x73, 0x90, 0xd3, 0xaf,
- 0xef, 0xa7, 0x76, 0xc9, 0x1d, 0x4e, 0xbc, 0x91, 0x86, 0x2a, 0x2c, 0x6e,
- 0x9a, 0x91, 0x9c, 0xf4, 0xe1, 0x70, 0x8d, 0xe4, 0x3b, 0xa2, 0x16, 0xa3,
- 0x09, 0xbd, 0x42, 0x58, 0x25, 0x93, 0xc4, 0x2a, 0x89, 0xaf, 0x44, 0xb0,
- 0xeb, 0xff, 0x33, 0xe3, 0xe3, 0x8c, 0x62, 0x68, 0xea, 0x9f, 0xcf, 0x69,
- 0xc6, 0xa8, 0xeb, 0xfb, 0x16, 0xfc, 0x8e, 0x1d, 0x77, 0x86, 0x4e, 0xaf,
- 0x07, 0x88, 0x02, 0xbb, 0xff, 0xed, 0xda, 0x2f, 0xe1, 0x62, 0xea, 0x7d,
- 0x36, 0x3a, 0x9d, 0x18, 0x98, 0x9c, 0x84, 0x97, 0xee, 0xf8, 0x19, 0xcc,
- 0x1d, 0x7d, 0xc8, 0xf5, 0xce, 0xa7, 0x3c, 0xd8, 0x2c, 0xbf, 0xb6, 0x65,
- 0xb3, 0xff, 0x76, 0x3a, 0xfc, 0xb4, 0x06, 0x00, 0xeb, 0x32, 0x75, 0xce,
- 0xb3, 0xad, 0xf3, 0xab, 0xa6, 0x96, 0x05, 0x68, 0x07, 0xad, 0xc3, 0x6b,
- 0xef, 0xea, 0x37, 0x3a, 0xe6, 0x60, 0xeb, 0xfa, 0x18, 0x7f, 0xe6, 0xc7,
- 0x5f, 0xee, 0x27, 0x77, 0x68, 0xb9, 0xd4, 0xad, 0x26, 0xd6, 0xe6, 0xd8,
- 0xf8, 0x84, 0x4b, 0x22, 0x11, 0x60, 0x96, 0xdf, 0xe6, 0x31, 0xa2, 0x18,
- 0xd1, 0xd7, 0xed, 0xd8, 0x81, 0xf4, 0xeb, 0x85, 0x43, 0xad, 0xa4, 0x37,
- 0xe1, 0x29, 0xbf, 0xff, 0x9d, 0x63, 0x92, 0xdf, 0xe3, 0x1c, 0x5b, 0xe7,
- 0xce, 0xbf, 0xff, 0x3f, 0x5e, 0x58, 0xb7, 0x93, 0x53, 0x41, 0x59, 0xd4,
- 0xe9, 0xa1, 0x32, 0xe3, 0xc2, 0x69, 0xe5, 0x8b, 0xfb, 0xb8, 0xea, 0x38,
- 0x9d, 0x78, 0x61, 0x67, 0x5d, 0xeb, 0x9d, 0x4d, 0x3d, 0xb4, 0x2b, 0x11,
- 0xaa, 0x56, 0x9f, 0x46, 0x2e, 0x7c, 0x32, 0x9f, 0xe3, 0xdc, 0x56, 0xcb,
- 0x4f, 0x2b, 0x67, 0x68, 0x59, 0x34, 0xac, 0x12, 0xb6, 0xf2, 0x94, 0x36,
- 0xa4, 0x7b, 0x72, 0x9c, 0xd5, 0xde, 0x59, 0x22, 0x47, 0xc6, 0xcc, 0xa5,
- 0x9e, 0xcb, 0xbc, 0x5c, 0xa0, 0xfe, 0x52, 0xf6, 0x22, 0x51, 0x87, 0xb0,
- 0xc6, 0x1a, 0x48, 0x96, 0xa7, 0x33, 0x7f, 0x3e, 0xa4, 0x18, 0xcf, 0x67,
- 0x43, 0xa9, 0x87, 0xa9, 0xe8, 0xe2, 0xfc, 0xc7, 0x50, 0xaa, 0x13, 0x97,
- 0xff, 0xf0, 0x65, 0x36, 0xff, 0xeb, 0xe6, 0xf3, 0xf8, 0x22, 0x14, 0x3a,
- 0xa6, 0x55, 0x34, 0x92, 0x8d, 0xef, 0xdd, 0x94, 0x44, 0x8d, 0x14, 0xed,
- 0xd9, 0xb9, 0xd7, 0xff, 0x82, 0x11, 0x41, 0x7e, 0x22, 0xf3, 0x47, 0x5a,
- 0x6c, 0x44, 0x7e, 0xe6, 0x6b, 0x16, 0xbf, 0x76, 0x51, 0x12, 0x34, 0x54,
- 0x77, 0xfe, 0x86, 0xcd, 0x9d, 0x94, 0x44, 0x8d, 0x13, 0x45, 0xf0, 0xbe,
- 0x6e, 0x75, 0x62, 0x27, 0x56, 0x67, 0xf4, 0xab, 0xfd, 0xe6, 0x27, 0x4d,
- 0xf4, 0xd8, 0xea, 0x98, 0xf9, 0xdc, 0xbe, 0xfd, 0xd9, 0x44, 0x48, 0xd1,
- 0x57, 0xdf, 0xd9, 0x39, 0xc7, 0x81, 0x3a, 0xd3, 0x61, 0xf0, 0x74, 0xce,
- 0xfd, 0xd9, 0x44, 0x48, 0xd1, 0x5b, 0x5f, 0xf3, 0x66, 0xce, 0xca, 0x22,
- 0x46, 0x89, 0x06, 0xd3, 0x61, 0xfc, 0x41, 0x9d, 0xff, 0xd3, 0x43, 0x66,
- 0xce, 0xca, 0x22, 0x46, 0x89, 0x0e, 0xff, 0xda, 0x9b, 0x3e, 0x80, 0xc1,
- 0x64, 0xeb, 0xd1, 0x12, 0x3c, 0x60, 0x74, 0xe7, 0xcb, 0x23, 0xeb, 0xb8,
- 0xae, 0x75, 0xff, 0x9b, 0xc7, 0xfe, 0x95, 0x9d, 0x4f, 0x82, 0x75, 0xff,
- 0xe5, 0x60, 0xac, 0x15, 0x9e, 0x3a, 0xc6, 0x38, 0x9d, 0x3a, 0xdb, 0x9d,
- 0x72, 0x09, 0xd4, 0x03, 0x4a, 0xc8, 0x8d, 0xfb, 0x30, 0x7d, 0xd1, 0xd7,
- 0xe8, 0x07, 0x97, 0x13, 0xaf, 0xfd, 0xdf, 0xf9, 0x18, 0x96, 0x0c, 0x8e,
- 0xbe, 0x94, 0x44, 0x8d, 0x16, 0x25, 0xe0, 0x8b, 0x4e, 0xbf, 0xd2, 0x7c,
- 0xef, 0xbe, 0xfc, 0xea, 0xd9, 0x1c, 0x38, 0x4f, 0xd3, 0xef, 0x96, 0x84,
- 0x6e, 0xfd, 0x9d, 0x71, 0x50, 0xeb, 0xf7, 0x99, 0xec, 0xeb, 0x9d, 0x7b,
- 0x4e, 0x27, 0x5b, 0x8e, 0x78, 0xa8, 0x57, 0x7f, 0xf3, 0xe6, 0xb0, 0x40,
- 0x9e, 0xb8, 0x9d, 0x78, 0x5f, 0x63, 0xac, 0xd1, 0x3d, 0xb0, 0xa0, 0x5e,
- 0x9e, 0x4f, 0x4e, 0xbf, 0x24, 0xe0, 0xc6, 0x8e, 0xbf, 0xe0, 0x73, 0x17,
- 0x91, 0xdd, 0x8e, 0xbf, 0x7f, 0xf0, 0xdd, 0x1d, 0x7f, 0xe0, 0xe6, 0xe0,
- 0x9d, 0xcc, 0x86, 0x4e, 0xad, 0xcf, 0xa2, 0x71, 0x3d, 0xce, 0xd3, 0xa9,
- 0xd1, 0xb5, 0x90, 0xa0, 0xe9, 0x2d, 0xff, 0x3e, 0xbc, 0xe7, 0x73, 0x19,
- 0x3a, 0xff, 0x67, 0x5b, 0xee, 0x63, 0x27, 0x5f, 0x37, 0xcf, 0x1c, 0xeb,
- 0xdd, 0x76, 0x9d, 0x50, 0x6f, 0xa7, 0x11, 0xdf, 0xce, 0xbc, 0x4e, 0xb2,
- 0x75, 0xfb, 0x01, 0xc7, 0xe1, 0xd7, 0xdd, 0x46, 0x15, 0xce, 0xb6, 0x84,
- 0xf2, 0xf4, 0x4d, 0x4e, 0x99, 0x8a, 0x38, 0xf0, 0x8a, 0x1d, 0xef, 0xff,
- 0x3a, 0xdd, 0xa0, 0x17, 0xe4, 0x67, 0x4e, 0xa3, 0xa9, 0xa7, 0xa1, 0x3c,
- 0x8d, 0x7f, 0xa4, 0x39, 0x38, 0x73, 0x47, 0x5f, 0xf6, 0xed, 0x8c, 0x1c,
- 0xfe, 0x8e, 0xad, 0xd1, 0x1d, 0xc2, 0x51, 0x32, 0xb4, 0xf1, 0xd7, 0x37,
- 0x47, 0x5a, 0x1a, 0x6a, 0x77, 0x13, 0xbf, 0x9f, 0x3e, 0x82, 0xc1, 0x55,
- 0x07, 0xa5, 0xe9, 0x3d, 0xff, 0xec, 0xfb, 0xb1, 0xe7, 0x6d, 0x62, 0xdd,
- 0x5c, 0xeb, 0xff, 0xb9, 0x09, 0xf6, 0xe2, 0x83, 0x9e, 0x9d, 0x7e, 0x16,
- 0x5f, 0x8e, 0x75, 0xfb, 0x39, 0xbc, 0x2b, 0x9d, 0x7d, 0xee, 0x9c, 0x4e,
- 0xbf, 0xdd, 0xe4, 0x26, 0x92, 0x71, 0xd4, 0xe7, 0xa9, 0x84, 0x34, 0x89,
- 0x83, 0xc2, 0x18, 0x93, 0x69, 0xfa, 0xfe, 0x61, 0xfb, 0xd8, 0x64, 0xeb,
- 0xff, 0x06, 0x3b, 0x8b, 0x49, 0xe7, 0x59, 0xd7, 0xdf, 0x7d, 0xda, 0x75,
- 0xfc, 0x9e, 0xcf, 0x0a, 0x7a, 0x75, 0x6c, 0x7a, 0x5d, 0x22, 0xa7, 0x47,
- 0x16, 0x17, 0x44, 0x24, 0x6f, 0xe9, 0xdd, 0x87, 0x49, 0xe3, 0xad, 0x87,
- 0x52, 0xcd, 0xf8, 0x98, 0x5f, 0xe0, 0x78, 0x07, 0x98, 0xef, 0x4e, 0xbf,
- 0xe7, 0x40, 0x7c, 0x63, 0x7d, 0x1d, 0x4e, 0x7d, 0xc2, 0x6f, 0x4a, 0xcb,
- 0x2e, 0x6e, 0x7c, 0x19, 0x56, 0xe4, 0x87, 0x7e, 0x01, 0x16, 0x46, 0x0e,
- 0xa2, 0x54, 0x9a, 0xf7, 0x84, 0x0a, 0x13, 0xb2, 0x3f, 0xd8, 0xc0, 0x96,
- 0x67, 0xc8, 0xda, 0xa2, 0x31, 0x9f, 0x61, 0x56, 0x24, 0x5a, 0x8d, 0x5b,
- 0xf1, 0x8e, 0x85, 0xc7, 0xcc, 0x23, 0xaf, 0xfe, 0xe2, 0x3f, 0xf9, 0x0a,
- 0x60, 0xfa, 0x75, 0xfd, 0x9f, 0x74, 0x5e, 0x8e, 0xbd, 0xaf, 0x3a, 0x3a,
- 0xff, 0xfb, 0x37, 0x6f, 0xc3, 0xb4, 0xdc, 0x85, 0xa6, 0x8e, 0xbf, 0xe0,
- 0xc6, 0x01, 0x37, 0x18, 0x3a, 0xf7, 0xc5, 0xce, 0xbb, 0x93, 0x62, 0x65,
- 0xcc, 0xa1, 0xc1, 0x58, 0x8f, 0x69, 0x4b, 0xc9, 0xb5, 0x4c, 0xab, 0xd9,
- 0xe5, 0x48, 0xdf, 0xd9, 0xd9, 0x44, 0x48, 0xd1, 0x66, 0xdf, 0x95, 0x4d,
- 0xc7, 0xe1, 0xd5, 0x31, 0xf1, 0x41, 0xc5, 0xfe, 0x5c, 0xce, 0x8b, 0xf3,
- 0xd3, 0xae, 0xc0, 0x1d, 0x7f, 0xe8, 0x6c, 0xd9, 0xd9, 0x44, 0x48, 0xd1,
- 0x40, 0x5f, 0xe4, 0x5b, 0xab, 0xf3, 0x36, 0x3a, 0xd3, 0x62, 0x25, 0x16,
- 0x2b, 0xc4, 0xab, 0xfa, 0x3f, 0xa6, 0xa7, 0xa7, 0x5f, 0xcd, 0x9b, 0x19,
- 0x76, 0x9d, 0x53, 0x1e, 0xdb, 0x96, 0xdc, 0x1e, 0x1d, 0x7f, 0x69, 0xd6,
- 0x2e, 0xc9, 0xd6, 0xe1, 0xd7, 0xbc, 0x8b, 0x27, 0x5d, 0x9f, 0xc3, 0x5d,
- 0xe8, 0x85, 0x7a, 0x88, 0x61, 0x5a, 0xbb, 0xc6, 0x8e, 0xbc, 0x10, 0x61,
- 0xd7, 0xfb, 0x3b, 0xf1, 0x75, 0xe8, 0xeb, 0x4f, 0x1d, 0x48, 0x7b, 0xfc,
- 0x1b, 0xf4, 0xc6, 0xfa, 0x51, 0x12, 0x34, 0x5b, 0xf7, 0xf7, 0x9f, 0xc4,
- 0xa3, 0xa7, 0x57, 0x4f, 0x6f, 0xd2, 0xdb, 0xec, 0x14, 0x64, 0xeb, 0xf7,
- 0xdb, 0xaf, 0x3a, 0x3a, 0xf6, 0xb8, 0x03, 0xaf, 0xde, 0x7e, 0x2f, 0xe9,
- 0xd4, 0xb3, 0xc5, 0x9c, 0x39, 0x7f, 0xf7, 0xf4, 0x9a, 0x71, 0xcf, 0xf1,
- 0x0e, 0xbc, 0x39, 0xc3, 0xa9, 0x67, 0xb7, 0x39, 0x06, 0xfc, 0x07, 0x57,
- 0x0a, 0xce, 0xbf, 0xe8, 0xd3, 0xe0, 0x83, 0x8e, 0x75, 0xff, 0xd8, 0xbe,
- 0xe6, 0xfc, 0x18, 0x57, 0xd8, 0xeb, 0xb5, 0xae, 0x9f, 0xe0, 0x9a, 0xd3,
- 0xa6, 0xed, 0x8f, 0xe8, 0x49, 0x10, 0xa6, 0xbe, 0x84, 0x1f, 0x9d, 0x7b,
- 0xaf, 0xf3, 0xaf, 0xe6, 0x60, 0x1c, 0x45, 0x9d, 0x7f, 0x7d, 0x30, 0x0e,
- 0xb3, 0xab, 0xe7, 0xb0, 0xc1, 0x6d, 0xda, 0x13, 0xaf, 0xed, 0xf4, 0xf2,
- 0xc5, 0x9d, 0x5d, 0x46, 0xc4, 0x39, 0xe8, 0x8c, 0x22, 0xb7, 0xdc, 0x50,
- 0x0b, 0x3a, 0xfb, 0x6e, 0xe0, 0x0e, 0xb3, 0x4e, 0xa7, 0x36, 0x58, 0x45,
- 0x58, 0x7e, 0x82, 0xab, 0x53, 0xe2, 0xef, 0x73, 0xc2, 0x71, 0xa4, 0x60,
- 0x77, 0xc8, 0x45, 0x21, 0x1f, 0x48, 0x39, 0x1f, 0x2f, 0xa7, 0xe3, 0x0f,
- 0x7f, 0xc2, 0xc2, 0xfe, 0x8d, 0xe6, 0x5c, 0x7c, 0xea, 0x99, 0x1c, 0xa3,
- 0x0b, 0x7b, 0x95, 0xa9, 0xf0, 0xeb, 0xcb, 0x8d, 0xce, 0xbe, 0xef, 0x73,
- 0xc9, 0xd7, 0xf2, 0x6b, 0x6c, 0x62, 0x65, 0x64, 0xf7, 0xdc, 0x82, 0x07,
- 0x2f, 0xdd, 0x94, 0x44, 0x8d, 0x14, 0xa5, 0xff, 0xf4, 0x7c, 0x73, 0x6e,
- 0xbf, 0x13, 0x99, 0xd3, 0xaf, 0x43, 0x66, 0xc4, 0x40, 0x7a, 0x67, 0x7f,
- 0xcd, 0x9b, 0x3b, 0x28, 0x89, 0x1a, 0x24, 0xeb, 0x4c, 0xb3, 0xfa, 0x83,
- 0x5a, 0x77, 0xf5, 0x7b, 0xda, 0x58, 0xe3, 0x57, 0xc1, 0x7a, 0x8b, 0x59,
- 0x0b, 0xb9, 0x46, 0x76, 0x90, 0x82, 0x57, 0x85, 0x03, 0x24, 0xfd, 0x85,
- 0xb2, 0xe9, 0xd6, 0x5c, 0x84, 0x74, 0x11, 0x7b, 0x0c, 0x91, 0x84, 0x8e,
- 0xa7, 0xbd, 0x7f, 0x08, 0x79, 0xd1, 0xa8, 0xdf, 0xbb, 0x28, 0x89, 0x1a,
- 0x21, 0xfb, 0xff, 0x43, 0x66, 0xce, 0xca, 0x22, 0x46, 0x89, 0x4e, 0xd3,
- 0x61, 0xfe, 0xac, 0xce, 0xff, 0x4d, 0x9d, 0x94, 0x44, 0x8d, 0x11, 0x3d,
- 0xfc, 0xca, 0x7f, 0x41, 0x59, 0xd7, 0xee, 0xca, 0x22, 0x46, 0x88, 0xc6,
- 0xd3, 0x39, 0xf0, 0xe1, 0x75, 0xff, 0xe9, 0x97, 0x0d, 0x9b, 0x3b, 0x28,
- 0x89, 0x1a, 0x27, 0x9b, 0xfa, 0x6f, 0x5c, 0x5b, 0xa3, 0xa9, 0xd3, 0x74,
- 0xd8, 0xa1, 0xb0, 0xa0, 0xe1, 0x3f, 0xd5, 0xef, 0xdd, 0x94, 0x44, 0x8d,
- 0x11, 0x05, 0xff, 0xa1, 0xb3, 0x67, 0x65, 0x11, 0x23, 0x44, 0xa9, 0x69,
- 0xb0, 0xff, 0x56, 0x67, 0x7f, 0xa6, 0xce, 0xca, 0x22, 0x46, 0x88, 0xa2,
- 0xff, 0x4d, 0x9d, 0x94, 0x44, 0x8d, 0x11, 0x95, 0xff, 0xe9, 0x97, 0x0d,
- 0x9b, 0x3b, 0x28, 0x89, 0x1a, 0x26, 0x5b, 0xfd, 0x36, 0x76, 0x51, 0x12,
- 0x34, 0x54, 0x97, 0xfa, 0x6c, 0xec, 0xa2, 0x24, 0x68, 0xae, 0xaf, 0xf4,
- 0xd9, 0xd9, 0x44, 0x48, 0xd1, 0x62, 0xdf, 0xfc, 0xb8, 0x6c, 0xd9, 0xd9,
- 0x44, 0x48, 0xd1, 0x3d, 0x5f, 0xf3, 0x13, 0x43, 0xa4, 0xf2, 0x2a, 0x3a,
- 0xff, 0xfc, 0xc8, 0xba, 0xe6, 0xcd, 0x23, 0x00, 0x88, 0x50, 0xeb, 0xff,
- 0x07, 0x5c, 0x86, 0xcd, 0x3e, 0x6b, 0xe7, 0x5f, 0xb3, 0xfa, 0x45, 0x9d,
- 0x7f, 0xf9, 0xf7, 0xfe, 0x32, 0x9d, 0xfe, 0x82, 0xae, 0x75, 0xe8, 0xde,
- 0x61, 0x3f, 0x4f, 0x93, 0x5b, 0xf8, 0x9a, 0x1f, 0x55, 0xb5, 0x0b, 0x9a,
- 0x99, 0x50, 0x5b, 0xa8, 0x24, 0x70, 0x17, 0xf4, 0xfa, 0x9c, 0x18, 0x64,
- 0xeb, 0xf6, 0x7d, 0x03, 0xa3, 0xae, 0x56, 0x55, 0xb8, 0xea, 0x56, 0xe3,
- 0xc8, 0x56, 0x24, 0xd7, 0xfd, 0x3f, 0xf9, 0x1c, 0xef, 0x5e, 0x47, 0x5f,
- 0x75, 0x7f, 0xdc, 0xeb, 0xd2, 0xce, 0x15, 0x79, 0x6f, 0xa3, 0xaf, 0xfd,
- 0x1a, 0xf1, 0xad, 0x63, 0x5a, 0xe7, 0x5f, 0xff, 0x86, 0x14, 0x4e, 0xbb,
- 0x5b, 0x9a, 0xf7, 0xd7, 0x3a, 0x94, 0x44, 0xa7, 0x0f, 0xef, 0xff, 0xee,
- 0xa2, 0xa8, 0x5c, 0xcf, 0xde, 0xa2, 0xa9, 0x07, 0x63, 0xaf, 0x93, 0x9e,
- 0x56, 0x75, 0xff, 0xe4, 0x53, 0xc6, 0x0c, 0x6f, 0xa5, 0x14, 0x83, 0xaa,
- 0x47, 0xe0, 0x24, 0x77, 0xff, 0xa3, 0x43, 0x9e, 0xcd, 0xc4, 0x94, 0x74,
- 0xeb, 0xf8, 0x18, 0xa7, 0xf2, 0x47, 0x5f, 0x71, 0xd7, 0x23, 0xaa, 0x0f,
- 0x3b, 0xe5, 0xb7, 0xe0, 0x23, 0x28, 0xc1, 0xd7, 0xff, 0x78, 0x77, 0x17,
- 0x5f, 0x8f, 0x1c, 0x9e, 0x3a, 0x9c, 0xfc, 0xc4, 0xa2, 0xff, 0xdc, 0xc6,
- 0x78, 0x9c, 0x7e, 0xb9, 0xd7, 0x46, 0xe7, 0x5f, 0xe8, 0xd4, 0x70, 0x23,
- 0xb1, 0xd4, 0x27, 0x90, 0x11, 0x6a, 0xd9, 0x5d, 0xaa, 0x42, 0xbf, 0xa4,
- 0x8b, 0x86, 0x87, 0x08, 0x46, 0x12, 0xff, 0x84, 0xa7, 0x92, 0x05, 0x50,
- 0x85, 0xbc, 0x31, 0xf3, 0xaf, 0x0a, 0x68, 0xeb, 0x31, 0x3e, 0x9b, 0x47,
- 0x1a, 0xbe, 0xec, 0xe8, 0x59, 0xd7, 0xe5, 0x8c, 0x7f, 0x47, 0x5f, 0x9b,
- 0xc7, 0xce, 0x9d, 0x5b, 0x9e, 0x67, 0x49, 0xab, 0x11, 0x7c, 0x85, 0x81,
- 0x6f, 0xbf, 0xee, 0x47, 0xdd, 0x9d, 0x22, 0xce, 0xbf, 0xce, 0xd1, 0xcd,
- 0xff, 0x87, 0x5e, 0xe0, 0x56, 0x75, 0x22, 0x21, 0x7a, 0x70, 0x13, 0x1b,
- 0xf0, 0xa8, 0x99, 0xa3, 0xaf, 0xcc, 0x47, 0xe2, 0x47, 0x5f, 0xfd, 0x8c,
- 0x47, 0xb9, 0x2e, 0x47, 0xba, 0x3a, 0xff, 0xda, 0x8d, 0xdc, 0x60, 0x18,
- 0xa1, 0xd4, 0x88, 0xcf, 0xe1, 0x30, 0x93, 0xfd, 0x16, 0xf2, 0xdf, 0x87,
- 0x5f, 0x08, 0x3c, 0x28, 0x75, 0xfd, 0x9a, 0x62, 0x07, 0x63, 0xab, 0x0f,
- 0xb2, 0x06, 0xc4, 0x92, 0xfc, 0x15, 0x34, 0x07, 0x3a, 0xfe, 0x7d, 0xdb,
- 0xa4, 0x13, 0xab, 0x13, 0x27, 0x48, 0x53, 0xf0, 0xb0, 0x4a, 0x2f, 0xff,
- 0xfc, 0x9d, 0xeb, 0xf9, 0xfa, 0x08, 0x5b, 0x9a, 0x00, 0x63, 0xad, 0x3a,
- 0xff, 0xfe, 0x1c, 0x53, 0x07, 0xc6, 0xbf, 0xcc, 0x5f, 0x97, 0xf4, 0xeb,
- 0x71, 0xd1, 0x95, 0x8d, 0x97, 0xd1, 0xbf, 0xd6, 0x75, 0xfb, 0x60, 0x75,
- 0x18, 0x3a, 0xfe, 0x04, 0x77, 0xd9, 0xec, 0x3a, 0xf9, 0xbc, 0xf3, 0x38,
- 0xeb, 0xff, 0x0a, 0x37, 0xfc, 0xce, 0xa6, 0x8e, 0xbf, 0xf4, 0x67, 0xae,
- 0x30, 0x0c, 0x50, 0xea, 0x69, 0xfc, 0x7a, 0x79, 0x7f, 0xa3, 0x7d, 0x7f,
- 0xf8, 0xae, 0x75, 0xff, 0xe7, 0xcd, 0xff, 0xc7, 0xf8, 0xbf, 0xba, 0x3a,
- 0xf6, 0xb8, 0xb3, 0xab, 0xe7, 0xca, 0x14, 0x9b, 0xdb, 0x27, 0x4e, 0xbf,
- 0x83, 0xaf, 0xeb, 0x3e, 0x75, 0xe6, 0x18, 0x60, 0xab, 0xff, 0xdf, 0x4f,
- 0xeb, 0x89, 0x3d, 0xe7, 0xae, 0xd2, 0xa6, 0x2f, 0xe9, 0x44, 0x63, 0x20,
- 0xe0, 0x53, 0x2f, 0xff, 0xf9, 0x3e, 0xd7, 0x1c, 0xff, 0x13, 0x3e, 0xeb,
- 0x4e, 0xb4, 0xea, 0x6a, 0xb7, 0x80, 0x13, 0xe1, 0x12, 0x14, 0xb2, 0x61,
- 0xd8, 0x4f, 0x2c, 0x8c, 0x61, 0x37, 0xf8, 0x74, 0x4e, 0x30, 0xbf, 0xed,
- 0xdb, 0xad, 0x60, 0x23, 0xe7, 0x5b, 0x0e, 0xa7, 0x3c, 0x85, 0x0e, 0x6d,
- 0x07, 0x5e, 0x7e, 0x68, 0xea, 0xdc, 0xd5, 0x20, 0x7d, 0xff, 0xfd, 0x1f,
- 0x4e, 0x42, 0xfc, 0x66, 0x9f, 0x3b, 0x82, 0x75, 0x93, 0xa7, 0xf2, 0x24,
- 0x37, 0xdf, 0x7d, 0xd8, 0x3a, 0xb8, 0x79, 0x2c, 0x13, 0x5c, 0xc7, 0x0e,
- 0xbf, 0xfc, 0xe3, 0x2f, 0x3d, 0x8f, 0x53, 0xfc, 0x73, 0xaf, 0xf2, 0x31,
- 0xac, 0xc1, 0xd8, 0xeb, 0xe7, 0xd3, 0xce, 0x3a, 0xff, 0xe7, 0x18, 0xfb,
- 0x5d, 0x48, 0x63, 0xe7, 0x57, 0x0f, 0x94, 0x24, 0x57, 0xbc, 0x44, 0x8e,
- 0xa9, 0x26, 0x6f, 0xe8, 0xbe, 0x92, 0xbf, 0x09, 0x75, 0x44, 0x57, 0xcb,
- 0xf2, 0xe2, 0x75, 0xfc, 0xc2, 0x91, 0x03, 0xe9, 0xd7, 0x05, 0x67, 0x52,
- 0x1e, 0x27, 0x0b, 0xaf, 0xf3, 0xc7, 0x78, 0xc4, 0x00, 0xab, 0x98, 0x60,
- 0xaa, 0x01, 0xe5, 0x30, 0x65, 0x7b, 0xe8, 0xae, 0x54, 0xc6, 0x8e, 0xfe,
- 0xde, 0x49, 0xae, 0x21, 0xd7, 0xc1, 0x68, 0x7e, 0x75, 0x22, 0x6e, 0x4c,
- 0xb3, 0x6a, 0x11, 0xdf, 0x2f, 0x9e, 0x2d, 0xb9, 0x8d, 0x1d, 0x6c, 0x3a,
- 0xdb, 0xe1, 0xa6, 0xf8, 0xbd, 0xf6, 0xed, 0x9f, 0x77, 0x3a, 0xff, 0xed,
- 0x68, 0x02, 0xe0, 0xe3, 0xff, 0x47, 0x53, 0xa2, 0x4f, 0x09, 0xc2, 0x53,
- 0x7f, 0xef, 0xa7, 0x63, 0xd5, 0x5f, 0xce, 0x1d, 0x7f, 0xc8, 0xc0, 0xe7,
- 0xd0, 0x3e, 0x9d, 0x7f, 0xa3, 0xbf, 0xd0, 0xa2, 0x87, 0x5f, 0xfe, 0xd6,
- 0x29, 0x81, 0xec, 0x01, 0xf8, 0xe7, 0x53, 0x53, 0x20, 0x42, 0xe5, 0x74,
- 0x08, 0x38, 0xd1, 0x95, 0xec, 0x4e, 0x9d, 0x7f, 0x9a, 0x8b, 0xe6, 0xf0,
- 0xae, 0x75, 0xf4, 0x75, 0xda, 0x75, 0x6c, 0x7e, 0x1b, 0x8d, 0x2c, 0xda,
- 0xfb, 0x8a, 0xe8, 0xb3, 0xaf, 0x0b, 0xfa, 0x75, 0xe7, 0x5e, 0x78, 0x37,
- 0xfa, 0x24, 0xbf, 0xf3, 0xef, 0xc7, 0x5c, 0xb8, 0x8c, 0x9d, 0x58, 0x8e,
- 0x24, 0x70, 0xe9, 0x9d, 0xfa, 0x51, 0xb6, 0x30, 0x75, 0xf9, 0xfa, 0x0c,
- 0x13, 0xa8, 0x4f, 0x37, 0xe5, 0x17, 0xff, 0x3f, 0xaf, 0xc5, 0x8c, 0x29,
- 0xc4, 0x3a, 0xd3, 0xf9, 0xd7, 0xf8, 0x1c, 0x71, 0x62, 0x37, 0x3a, 0xff,
- 0xe4, 0x07, 0x1e, 0x4f, 0xec, 0x0f, 0xa7, 0x5f, 0xff, 0xf2, 0xe0, 0x77,
- 0x6c, 0xcc, 0x62, 0x4e, 0xc1, 0xc0, 0x43, 0x4f, 0x17, 0xad, 0xf7, 0xc4,
- 0x3b, 0x1d, 0x48, 0x89, 0x61, 0x74, 0xa7, 0x4e, 0x9b, 0xa4, 0x2b, 0x43,
- 0x81, 0x5d, 0x19, 0x86, 0x1b, 0x37, 0xcd, 0x9f, 0xd5, 0x99, 0xf0, 0xeb,
- 0xe4, 0x18, 0x01, 0xd7, 0xb6, 0x5a, 0x1d, 0x40, 0x37, 0x62, 0x3f, 0x5b,
- 0xa2, 0x31, 0x1b, 0x2f, 0xff, 0xb3, 0xfa, 0xc6, 0x78, 0xf3, 0xb3, 0x9c,
- 0x73, 0xaf, 0xff, 0xff, 0xc9, 0x9b, 0xe9, 0x31, 0x8f, 0x19, 0xbb, 0x74,
- 0x9f, 0xd2, 0x6e, 0x00, 0x07, 0x63, 0xaf, 0xff, 0xc8, 0x20, 0xf1, 0xe7,
- 0xe9, 0xa8, 0x41, 0x0b, 0x4e, 0xa1, 0x4c, 0xbb, 0xea, 0x13, 0xa1, 0x11,
- 0x7f, 0xb6, 0x8f, 0xfb, 0xe4, 0x5a, 0x75, 0xe5, 0x30, 0x07, 0x5f, 0xdc,
- 0x8e, 0xc9, 0xfe, 0x75, 0xd0, 0x03, 0xaf, 0xee, 0xc6, 0xb9, 0x0d, 0x3a,
- 0xdb, 0x9d, 0x72, 0x30, 0x75, 0xde, 0x7d, 0x3a, 0x99, 0x35, 0xfe, 0x8b,
- 0x5e, 0x6c, 0x00, 0xeb, 0x98, 0x60, 0xea, 0x6a, 0x35, 0xf0, 0x56, 0x45,
- 0x88, 0x81, 0xa2, 0x36, 0x06, 0xef, 0x7f, 0xcf, 0xa5, 0x4c, 0x7a, 0xd7,
- 0xff, 0xfd, 0xc0, 0xc2, 0x8b, 0x80, 0x66, 0x0a, 0x9a, 0xd6, 0x0f, 0xa7,
- 0x5f, 0xff, 0xcd, 0x8d, 0x69, 0xf3, 0x60, 0xb4, 0x1d, 0x18, 0x60, 0xeb,
- 0xbe, 0xe0, 0x46, 0x0a, 0x33, 0x53, 0x55, 0x4a, 0x00, 0x73, 0x78, 0xd6,
- 0x52, 0x1e, 0x57, 0xfd, 0x9f, 0xe3, 0xf7, 0xf9, 0x23, 0xaf, 0x3f, 0x59,
- 0x3a, 0x9d, 0x73, 0xbf, 0x23, 0x51, 0x43, 0x78, 0x95, 0x94, 0x29, 0x53,
- 0xc6, 0xf7, 0xb5, 0x0c, 0x9d, 0x7d, 0x9f, 0x85, 0x47, 0x56, 0xe6, 0xf8,
- 0x47, 0x2f, 0xb3, 0x7d, 0xa7, 0x1d, 0x7f, 0xc2, 0x0c, 0x10, 0xb7, 0x34,
- 0x75, 0x74, 0xf6, 0xe0, 0x96, 0xf9, 0xf3, 0xc8, 0x0e, 0xbf, 0xca, 0x27,
- 0xe3, 0x8c, 0x2b, 0x9d, 0x7f, 0xdd, 0xc6, 0x79, 0x9a, 0x81, 0x3a, 0xff,
- 0xb9, 0x8d, 0xc0, 0xcf, 0xd0, 0x27, 0x5f, 0xff, 0xe4, 0x1c, 0xdf, 0xea,
- 0x47, 0xf8, 0xfc, 0xc9, 0xd0, 0xd3, 0xaa, 0x49, 0x96, 0x21, 0x17, 0x4d,
- 0xfe, 0x6f, 0x38, 0xee, 0xff, 0xcf, 0xa8, 0xe2, 0x02, 0x49, 0xb1, 0xd5,
- 0x88, 0x89, 0x0a, 0x65, 0xe7, 0x1f, 0x9d, 0x7f, 0x93, 0x89, 0xd6, 0xb2,
- 0xe7, 0x5f, 0x47, 0x5d, 0xa7, 0x5f, 0xff, 0xc8, 0x30, 0x83, 0xef, 0x5f,
- 0x90, 0x9f, 0x7e, 0x1d, 0x42, 0x7e, 0xdf, 0x20, 0xbf, 0x27, 0xf4, 0x1d,
- 0x8e, 0xbf, 0xfe, 0x71, 0x4f, 0x7f, 0xbc, 0x93, 0xbe, 0x5c, 0x07, 0x52,
- 0x22, 0x69, 0x64, 0x3f, 0x28, 0xbf, 0x74, 0x32, 0xe3, 0x9d, 0x7f, 0x75,
- 0x96, 0xa7, 0xf4, 0x75, 0x85, 0xcf, 0x57, 0x09, 0xef, 0xfb, 0x19, 0x86,
- 0x63, 0x76, 0xe8, 0xeb, 0xfd, 0x9b, 0x60, 0xed, 0x8c, 0x1d, 0x7e, 0x7e,
- 0xf7, 0x38, 0x75, 0xfc, 0x30, 0xa3, 0xad, 0xce, 0xa6, 0x9e, 0x88, 0x49,
- 0xaf, 0x9f, 0x65, 0x14, 0x3a, 0xe4, 0x9c, 0x75, 0xb8, 0x75, 0x2b, 0x9a,
- 0x70, 0x8b, 0xde, 0x03, 0xac, 0xeb, 0xfd, 0x9e, 0xe3, 0x2f, 0xbe, 0x8e,
- 0xa7, 0x3c, 0xfc, 0x1b, 0xbf, 0xb9, 0x0d, 0x7d, 0x34, 0xeb, 0xfe, 0xce,
- 0x26, 0xfa, 0xe0, 0x74, 0x75, 0xd8, 0x32, 0x3e, 0x5f, 0x4b, 0x2f, 0xe1,
- 0x8f, 0x41, 0x82, 0x75, 0xfc, 0xb4, 0x9e, 0xce, 0xa8, 0x75, 0xe6, 0x18,
- 0x60, 0xab, 0xff, 0x9f, 0xa2, 0x18, 0xf3, 0x8c, 0xba, 0xce, 0x98, 0xbf,
- 0xa7, 0x5d, 0x23, 0x68, 0xd6, 0x46, 0x84, 0xaf, 0x08, 0x46, 0x49, 0x7a,
- 0x74, 0xb8, 0x42, 0x70, 0x8a, 0x12, 0xc5, 0xcf, 0x50, 0x85, 0xf9, 0x68,
- 0x4a, 0xd8, 0x4f, 0xbe, 0xef, 0x73, 0x87, 0x5f, 0xdc, 0x45, 0x4a, 0x82,
- 0xa1, 0xd4, 0xe7, 0xa7, 0x22, 0x1b, 0x4f, 0xc7, 0x59, 0x0e, 0xbf, 0xef,
- 0xbf, 0x75, 0xc7, 0x1f, 0x9d, 0x69, 0xf8, 0xeb, 0xfe, 0xfb, 0xf7, 0x5c,
- 0x71, 0xf9, 0xd7, 0x69, 0xce, 0xbc, 0xb0, 0x39, 0xd7, 0xf8, 0x7f, 0x0c,
- 0xe9, 0xfe, 0x75, 0x21, 0xe6, 0xc0, 0xdd, 0xf2, 0x46, 0x48, 0xeb, 0xff,
- 0x64, 0xe1, 0xcd, 0x32, 0x2e, 0x03, 0xaf, 0xa4, 0x07, 0xd8, 0xeb, 0xbd,
- 0x73, 0xaf, 0x69, 0x3a, 0x75, 0x61, 0xe9, 0xfa, 0x45, 0xf1, 0x6b, 0xfc,
- 0xdc, 0x14, 0x06, 0x09, 0xd7, 0xbf, 0xa9, 0x9d, 0x3d, 0xcc, 0x15, 0x64,
- 0xdf, 0x8c, 0x5e, 0x90, 0x08, 0xfe, 0xa1, 0x23, 0xf2, 0xfb, 0xb4, 0xe7,
- 0x5e, 0x58, 0x1c, 0xeb, 0xfc, 0x3f, 0x86, 0x74, 0xff, 0x3a, 0x90, 0xf3,
- 0x60, 0x6e, 0xf9, 0x23, 0x24, 0x75, 0xff, 0xb2, 0x70, 0xe6, 0x99, 0x17,
- 0x01, 0xd7, 0xd2, 0x03, 0xec, 0x75, 0xfc, 0xcf, 0xa8, 0xaf, 0x0c, 0x9d,
- 0x77, 0xae, 0x75, 0xed, 0x27, 0x4e, 0xac, 0x44, 0x2c, 0x88, 0xbd, 0x32,
- 0xf8, 0xb5, 0xfe, 0x6e, 0x0a, 0x03, 0x04, 0xeb, 0xf8, 0x60, 0x18, 0xa4,
- 0xce, 0xb9, 0x20, 0x01, 0x5c, 0x0f, 0x94, 0xa1, 0x36, 0x61, 0x13, 0xc6,
- 0x2f, 0x48, 0x04, 0x7f, 0x50, 0xc3, 0xf9, 0xed, 0xff, 0xdd, 0x7d, 0xf4,
- 0x2e, 0xbc, 0xdf, 0xe7, 0x5f, 0xff, 0xa0, 0x19, 0x82, 0xa7, 0x91, 0x71,
- 0xd9, 0x3a, 0x75, 0xe8, 0xee, 0xc7, 0x90, 0x4a, 0xf9, 0xb9, 0xbb, 0x4f,
- 0x20, 0x95, 0xed, 0x20, 0x0f, 0x20, 0x95, 0xcc, 0x30, 0x79, 0x04, 0xaa,
- 0x48, 0xa5, 0x64, 0xa7, 0xe5, 0xec, 0x14, 0x5d, 0x1f, 0x2c, 0x82, 0x49,
- 0x8d, 0xfd, 0xfd, 0x9c, 0xcc, 0x15, 0x0e, 0xbd, 0x03, 0xef, 0x85, 0xf4,
- 0xd7, 0x9c, 0xb1, 0xec, 0x30, 0x56, 0x88, 0x31, 0x9c, 0x7c, 0xd2, 0xfa,
- 0x7b, 0x23, 0x87, 0x5b, 0x15, 0xd1, 0x43, 0xeb, 0xf5, 0x9a, 0x75, 0xfe,
- 0x65, 0xa1, 0xdb, 0xe9, 0xb1, 0x57, 0xf9, 0x1a, 0x18, 0xd7, 0x10, 0xeb,
- 0xfb, 0x27, 0x42, 0xf3, 0x87, 0x59, 0xa5, 0x5e, 0x8e, 0xec, 0x55, 0x15,
- 0x4e, 0x6d, 0xa4, 0x20, 0xb1, 0xcb, 0xcf, 0xec, 0x8a, 0x98, 0xd6, 0xd2,
- 0xd1, 0x7a, 0x30, 0x90, 0xa7, 0x4c, 0x57, 0x21, 0xdd, 0x7c, 0x18, 0xeb,
- 0x4e, 0xb2, 0xce, 0xbb, 0x1a, 0x03, 0x62, 0xc9, 0x0d, 0xf9, 0x8c, 0x65,
- 0x16, 0x75, 0xfd, 0x27, 0x65, 0xaf, 0xe9, 0x56, 0x43, 0xaf, 0xfb, 0x60,
- 0xb4, 0x1c, 0x0c, 0x09, 0xd7, 0xf2, 0x3a, 0xf6, 0xc6, 0x0e, 0xbf, 0x66,
- 0xcb, 0xc5, 0x9d, 0x7b, 0x49, 0xd3, 0xa8, 0x4f, 0x0b, 0xe4, 0xf7, 0xf0,
- 0xc7, 0xbe, 0x87, 0x47, 0x5f, 0xc8, 0xa7, 0x97, 0x5c, 0xc0, 0x4c, 0x1b,
- 0x03, 0xfa, 0x73, 0xa6, 0xff, 0x90, 0xd6, 0x27, 0x98, 0x85, 0x03, 0x19,
- 0xa5, 0xf0, 0xe6, 0xc1, 0x3a, 0x9a, 0xb8, 0x5a, 0x02, 0xcc, 0x10, 0xe4,
- 0x69, 0x62, 0xb1, 0xa8, 0xfe, 0x7e, 0x69, 0x7f, 0xfe, 0xdb, 0xbd, 0xc0,
- 0x42, 0xf9, 0x1f, 0x17, 0x64, 0xeb, 0xff, 0xff, 0xc1, 0xe8, 0x59, 0x18,
- 0xf7, 0x5a, 0xc5, 0x30, 0x3d, 0x80, 0x3f, 0x1c, 0xeb, 0xe5, 0x5c, 0x0f,
- 0x93, 0xaf, 0x30, 0xc3, 0x05, 0x5c, 0xd7, 0x2a, 0x62, 0xfe, 0x9d, 0x33,
- 0x7d, 0x95, 0x77, 0x78, 0xea, 0x2d, 0xfc, 0xa3, 0xf7, 0xb9, 0xc3, 0xaf,
- 0xed, 0x99, 0x6c, 0xff, 0xdd, 0x8e, 0xbe, 0xe4, 0x6e, 0xc1, 0xd7, 0xed,
- 0xba, 0x8e, 0xb3, 0xaf, 0xff, 0x9f, 0xcf, 0xc5, 0xfd, 0x8f, 0xfb, 0xe4,
- 0x5a, 0x75, 0x2b, 0x48, 0xd3, 0x43, 0x68, 0x23, 0xf9, 0x3d, 0xef, 0x20,
- 0x64, 0xeb, 0xcd, 0x41, 0x3a, 0xfb, 0x6f, 0x2a, 0x98, 0x3a, 0xff, 0xfe,
- 0x0c, 0x6d, 0x20, 0xed, 0xfc, 0xe0, 0xe7, 0xf8, 0x87, 0x5f, 0x9d, 0x91,
- 0x0e, 0x8e, 0xae, 0x22, 0x0b, 0xeb, 0x77, 0xf4, 0x0f, 0xb9, 0xf5, 0x0e,
- 0xad, 0x93, 0x33, 0x68, 0xfc, 0x0d, 0x7e, 0x15, 0x53, 0xc4, 0x77, 0x46,
- 0x8e, 0xb8, 0x33, 0xf1, 0xd4, 0x26, 0xc0, 0x22, 0xb7, 0x44, 0xd3, 0xeb,
- 0xb9, 0x10, 0x9f, 0x1e, 0x67, 0xf2, 0xf5, 0x6c, 0x7c, 0xac, 0x08, 0xde,
- 0x5e, 0x86, 0xd1, 0xc7, 0x36, 0x16, 0x60, 0x94, 0x4b, 0x93, 0x90, 0x4a,
- 0x43, 0x92, 0x51, 0x87, 0x6f, 0x1a, 0xd2, 0x47, 0x8a, 0xcc, 0xa2, 0xce,
- 0xc7, 0x3c, 0xb9, 0x44, 0x3c, 0x9d, 0xd6, 0x88, 0x51, 0xfa, 0xf8, 0x31,
- 0xeb, 0x6a, 0x75, 0x17, 0xf4, 0xd4, 0x60, 0xc7, 0x50, 0xc1, 0xfc, 0xf4,
- 0x60, 0x1e, 0x63, 0x73, 0x55, 0x08, 0x3b, 0xf2, 0xf1, 0x23, 0xd3, 0xaf,
- 0xdd, 0x94, 0x44, 0x8d, 0x14, 0x55, 0xfa, 0x65, 0xc3, 0x66, 0x73, 0xd9,
- 0xc2, 0x6b, 0xfd, 0x36, 0x76, 0x51, 0x12, 0x34, 0x5d, 0x17, 0xff, 0x4d,
- 0x0d, 0x9b, 0x3b, 0x28, 0x89, 0x1a, 0x24, 0xbb, 0xf7, 0x65, 0x11, 0x23,
- 0x45, 0xe5, 0x74, 0x4e, 0x3a, 0xd3, 0x61, 0xe5, 0x4f, 0x19, 0xd3, 0xbe,
- 0x06, 0xd6, 0xc5, 0x0d, 0x3f, 0xc3, 0xf9, 0x2b, 0xb2, 0x7e, 0xb3, 0xfe,
- 0x4a, 0x4a, 0x1b, 0x72, 0x8f, 0xa9, 0x51, 0x5f, 0x3f, 0x09, 0xfc, 0xe8,
- 0x4d, 0xdf, 0xfe, 0x99, 0x70, 0xd9, 0xb3, 0xb2, 0x88, 0x91, 0xa2, 0x59,
- 0xb8, 0x3c, 0x3a, 0xff, 0x20, 0x39, 0x88, 0x2a, 0x1d, 0x7d, 0xc7, 0x57,
- 0x59, 0xd7, 0x83, 0x28, 0x3a, 0x9a, 0x7e, 0x0a, 0xe6, 0x3e, 0x49, 0x2f,
- 0xe0, 0x7c, 0x30, 0xdd, 0x1d, 0x7f, 0xee, 0x3f, 0x11, 0x4f, 0xea, 0x3d,
- 0x3a, 0xfa, 0x51, 0x12, 0x34, 0x46, 0x77, 0xf2, 0x3a, 0xf6, 0xc6, 0x0e,
- 0xb8, 0x5a, 0x75, 0x96, 0x75, 0xf9, 0x3b, 0xc8, 0x9b, 0xa7, 0xa4, 0xb2,
- 0xdf, 0x22, 0xb7, 0xf4, 0x35, 0x3b, 0x1d, 0x3a, 0xff, 0xed, 0x20, 0x75,
- 0x82, 0x16, 0xe6, 0x8e, 0xbd, 0xa7, 0xdc, 0xea, 0x6a, 0x72, 0xbd, 0x3f,
- 0x5b, 0xf8, 0xa7, 0x68, 0xaf, 0xe8, 0x57, 0xfc, 0xdd, 0x63, 0xf8, 0x7d,
- 0x2c, 0xeb, 0xff, 0xbe, 0x9d, 0x8f, 0x7c, 0x6e, 0xd7, 0x59, 0xd7, 0xe1,
- 0x76, 0xea, 0x0e, 0xa4, 0x3e, 0xc9, 0xc8, 0xf7, 0xff, 0xff, 0xd9, 0xff,
- 0xa2, 0xfa, 0x99, 0xb8, 0x87, 0xef, 0xcf, 0x13, 0x93, 0xec, 0xb9, 0xd7,
- 0xe5, 0x3f, 0xf7, 0x59, 0xd7, 0x79, 0x69, 0xd4, 0x87, 0x81, 0x05, 0x17,
- 0xff, 0xc1, 0xfe, 0xb7, 0x6b, 0x8f, 0xba, 0xf0, 0x11, 0x3a, 0xf3, 0xfd,
- 0xce, 0xb2, 0x00, 0xfb, 0x67, 0x29, 0xdd, 0xc6, 0x4e, 0xbf, 0xdb, 0xe8,
- 0x73, 0xa0, 0x73, 0xa9, 0x0f, 0x26, 0x05, 0xef, 0xbf, 0xc0, 0xcf, 0x1d,
- 0x7f, 0xdf, 0x46, 0x34, 0xfc, 0x85, 0x73, 0xad, 0x88, 0x7c, 0x0b, 0x25,
- 0xbd, 0xe7, 0x27, 0xf3, 0xaf, 0xf9, 0xd3, 0x88, 0xe2, 0xc8, 0x4e, 0xac,
- 0x3d, 0x8e, 0x11, 0x5c, 0x8c, 0x1d, 0x72, 0xac, 0x3a, 0xb4, 0x6b, 0x7e,
- 0x2d, 0x7f, 0xb3, 0x4f, 0xfd, 0x71, 0x0e, 0xbe, 0xf5, 0x37, 0x69, 0xd7,
- 0xf9, 0xc7, 0xe9, 0xb0, 0xb9, 0xd5, 0xe9, 0xe9, 0x89, 0x1d, 0xa6, 0x9f,
- 0x17, 0xdb, 0x5e, 0x10, 0xdb, 0x1a, 0x64, 0x78, 0x5b, 0xab, 0xb3, 0x0a,
- 0x5e, 0x91, 0xf2, 0x18, 0x11, 0x08, 0xdf, 0x5c, 0x86, 0x10, 0x1a, 0x7e,
- 0x9c, 0x9d, 0x3c, 0x43, 0xe6, 0x10, 0x97, 0xff, 0xa6, 0x5c, 0x36, 0x6c,
- 0xec, 0xa2, 0x24, 0x68, 0x9a, 0x6f, 0xff, 0x4c, 0xb8, 0x6c, 0xd9, 0xd9,
- 0x44, 0x48, 0xd1, 0x38, 0xdf, 0xfe, 0x99, 0x70, 0xd9, 0xb3, 0xb2, 0x88,
- 0x91, 0xa2, 0x81, 0xbf, 0x76, 0x51, 0x12, 0x34, 0x5c, 0x17, 0xf0, 0xe7,
- 0xe4, 0x9a, 0x3a, 0xe7, 0x43, 0xaf, 0xf0, 0xb5, 0xd0, 0x18, 0xb3, 0xab,
- 0x11, 0x44, 0xb3, 0x3e, 0x15, 0x84, 0x52, 0xfc, 0xd9, 0x94, 0x9f, 0x54,
- 0x3a, 0xa6, 0x3e, 0xc7, 0x3c, 0xbf, 0xb1, 0x96, 0xb8, 0xb4, 0xeb, 0xe7,
- 0xf7, 0x18, 0x3a, 0xe4, 0x98, 0x4f, 0x3b, 0xc9, 0x65, 0xff, 0x36, 0x6c,
- 0xec, 0xa2, 0x24, 0x68, 0x92, 0x6d, 0x37, 0x0f, 0xd2, 0x0b, 0xee, 0x63,
- 0xd3, 0xaf, 0xf4, 0x7c, 0x73, 0x68, 0x13, 0xaf, 0xec, 0x18, 0xdd, 0xba,
- 0x3a, 0xfe, 0x75, 0xf7, 0x01, 0xf3, 0xae, 0x89, 0x80, 0x8a, 0x05, 0x06,
- 0x3a, 0x61, 0xa2, 0xca, 0xd9, 0x99, 0xa6, 0xd9, 0xfc, 0x49, 0x46, 0x0c,
- 0xca, 0xbf, 0xaa, 0xfa, 0x8d, 0x97, 0xf0, 0xe4, 0x9d, 0x0c, 0x8b, 0xff,
- 0x29, 0x13, 0x67, 0x65, 0x11, 0x23, 0x45, 0xa9, 0x7f, 0xe8, 0x6c, 0xd9,
- 0xd9, 0x44, 0x48, 0xd1, 0x2a, 0xdc, 0x8c, 0x1d, 0x47, 0x5a, 0x65, 0x11,
- 0x6a, 0xb4, 0xbf, 0xa5, 0x2a, 0x16, 0xbf, 0xd3, 0x67, 0x65, 0x11, 0x23,
- 0x44, 0x53, 0x7f, 0xa6, 0xce, 0xca, 0x22, 0x46, 0x88, 0xd2, 0xe0, 0xf0,
- 0xeb, 0xff, 0x03, 0x16, 0x9d, 0xcd, 0x32, 0xe7, 0x5f, 0xff, 0xf4, 0x07,
- 0x5c, 0xc0, 0x79, 0xf3, 0xa4, 0xf3, 0xf4, 0xd3, 0x3e, 0x4e, 0xa4, 0x45,
- 0x62, 0xb9, 0xed, 0xf4, 0xa2, 0x24, 0x68, 0xa7, 0xee, 0xfb, 0x9d, 0x5d,
- 0x3c, 0x2f, 0x96, 0xdf, 0xfb, 0xec, 0xbf, 0xf9, 0x0c, 0xf8, 0xc3, 0xaf,
- 0xff, 0x22, 0xc4, 0x3c, 0x4e, 0xe6, 0x99, 0x73, 0xaf, 0xfe, 0x0f, 0xfa,
- 0x16, 0x75, 0x28, 0x67, 0x47, 0x5f, 0xfd, 0x8c, 0x84, 0x76, 0xd4, 0xa1,
- 0x9d, 0x1d, 0x69, 0xa7, 0xc5, 0x4c, 0x2f, 0x0c, 0x2c, 0x67, 0x42, 0x28,
- 0x41, 0x14, 0x8f, 0xa3, 0xdf, 0xfe, 0x99, 0x70, 0xd9, 0xb3, 0xb2, 0x88,
- 0x91, 0xa2, 0x6a, 0xbf, 0xd3, 0x67, 0x65, 0x11, 0x23, 0x45, 0x77, 0x7d,
- 0x28, 0x89, 0x1a, 0x2b, 0xeb, 0xcc, 0x30, 0xc1, 0x56, 0x12, 0xa6, 0x2f,
- 0xeb, 0xa7, 0xd6, 0xb4, 0xcb, 0xcd, 0x7d, 0xce, 0xbc, 0xce, 0x70, 0xeb,
- 0xff, 0x67, 0x18, 0x8f, 0xe9, 0xf3, 0x63, 0xad, 0xf3, 0xaf, 0xf9, 0x3b,
- 0x9b, 0x23, 0x70, 0x07, 0x57, 0x4f, 0x1e, 0x04, 0x2f, 0xdb, 0xaa, 0xe0,
- 0x7c, 0x9d, 0x6e, 0x9d, 0x47, 0x5b, 0x88, 0x5d, 0x74, 0x42, 0xd3, 0x62,
- 0x6d, 0x8c, 0x91, 0x40, 0xe0, 0x8e, 0x6a, 0x10, 0xa1, 0x21, 0x9e, 0x47,
- 0xbf, 0xfd, 0x32, 0xe1, 0xb3, 0x67, 0x65, 0x11, 0x23, 0x44, 0xf7, 0x7e,
- 0xe3, 0xaa, 0x8d, 0xce, 0xbf, 0x76, 0x51, 0x12, 0x34, 0x5c, 0x36, 0x99,
- 0xcf, 0x73, 0x0a, 0x6f, 0xfe, 0x9a, 0x1b, 0x36, 0x76, 0x51, 0x12, 0x34,
- 0x49, 0xf4, 0xeb, 0xf4, 0x5b, 0x23, 0xb4, 0xfd, 0x49, 0x54, 0x12, 0x72,
- 0x65, 0x5f, 0xb2, 0x85, 0xb8, 0xe5, 0xa8, 0x59, 0xce, 0x27, 0xbf, 0xd3,
- 0x67, 0x65, 0x11, 0x23, 0x44, 0x55, 0x7e, 0xec, 0xa2, 0x24, 0x68, 0xa6,
- 0x6f, 0xe4, 0xe6, 0x46, 0xfe, 0x9d, 0x69, 0xb0, 0xf8, 0x27, 0x8c, 0xef,
- 0xff, 0x4c, 0xb8, 0x6c, 0xd9, 0xd9, 0x44, 0x48, 0xd1, 0x33, 0xdf, 0xfe,
- 0x99, 0x70, 0xd9, 0xb3, 0xb2, 0x88, 0x91, 0xa2, 0x8d, 0xad, 0x93, 0x78,
- 0x04, 0x27, 0xd4, 0x2b, 0xfa, 0xbd, 0xff, 0xa1, 0xb3, 0x67, 0x65, 0x11,
- 0x23, 0x44, 0x75, 0x7f, 0xf7, 0x76, 0x9b, 0x43, 0x9f, 0xd3, 0xac, 0xea,
- 0x99, 0x11, 0xee, 0x95, 0x70, 0x78, 0x75, 0xf4, 0xa4, 0x19, 0x1d, 0x7e,
- 0xc1, 0x06, 0x6c, 0x75, 0xfe, 0x77, 0x96, 0x77, 0xb8, 0x75, 0x21, 0xeb,
- 0x09, 0x35, 0xff, 0x87, 0x14, 0x86, 0x75, 0xc7, 0x01, 0xd7, 0xd2, 0x88,
- 0x91, 0xa2, 0x9a, 0xbf, 0x66, 0xec, 0x47, 0x0e, 0xa4, 0x44, 0x9f, 0x4f,
- 0x84, 0xb6, 0xff, 0xff, 0xb0, 0x7f, 0xa4, 0x96, 0x0e, 0xa5, 0xc4, 0xe4,
- 0xbc, 0xec, 0x75, 0xff, 0x6a, 0x37, 0xc6, 0x5f, 0x9a, 0x3a, 0xee, 0x20,
- 0xa2, 0x83, 0xec, 0xf7, 0xff, 0x37, 0x88, 0x3b, 0x68, 0x2f, 0xd6, 0x4e,
- 0xbf, 0xed, 0x6a, 0x49, 0xde, 0xa6, 0xc7, 0x5d, 0xb3, 0x27, 0x5c, 0xea,
- 0x1d, 0x7f, 0x23, 0xaf, 0x6c, 0x60, 0xeb, 0xff, 0xec, 0xff, 0x31, 0xbd,
- 0x81, 0xff, 0x21, 0xa7, 0x5c, 0xfe, 0x9d, 0x7f, 0xa3, 0x77, 0x92, 0x4a,
- 0x6e, 0xa2, 0x40, 0x4b, 0x7c, 0xa6, 0xd2, 0x26, 0x31, 0xc1, 0x8d, 0x42,
- 0x9a, 0xfd, 0xfe, 0x31, 0x1b, 0x1d, 0x69, 0xa7, 0xc5, 0xc3, 0x07, 0x16,
- 0x03, 0xc6, 0x42, 0xce, 0x50, 0xce, 0xdc, 0xb7, 0xa8, 0xbf, 0x8d, 0x47,
- 0xc9, 0xad, 0xfb, 0xb2, 0x88, 0x91, 0xa2, 0xaa, 0xbf, 0xf4, 0x36, 0x6c,
- 0xec, 0xa2, 0x24, 0x68, 0x9b, 0x6d, 0x36, 0x1f, 0xea, 0xcc, 0xef, 0xf4,
- 0xd9, 0xd9, 0x44, 0x48, 0xd1, 0x5f, 0xdf, 0xbb, 0x28, 0x89, 0x1a, 0x2c,
- 0x6b, 0x95, 0x34, 0xeb, 0x4d, 0x87, 0x96, 0xc9, 0x9d, 0xfb, 0x52, 0xe3,
- 0xa8, 0x75, 0xff, 0x67, 0xff, 0x9d, 0x06, 0x09, 0xd7, 0x94, 0x6e, 0x1d,
- 0x69, 0x84, 0xf4, 0xb4, 0x6d, 0x64, 0x99, 0x14, 0x5d, 0x7a, 0xbf, 0x76,
- 0x51, 0x12, 0x34, 0x5a, 0xb7, 0xfe, 0x86, 0xcd, 0x9d, 0x94, 0x44, 0x8d,
- 0x14, 0x15, 0xa6, 0xc3, 0xfd, 0x59, 0x9d, 0xfe, 0x71, 0xf5, 0xd5, 0xe1,
- 0x67, 0x5d, 0xd7, 0x3a, 0x9a, 0x79, 0x2a, 0x8d, 0x2f, 0xa5, 0x11, 0x23,
- 0x45, 0xc5, 0x7f, 0x06, 0x37, 0x06, 0x74, 0xea, 0xe9, 0xed, 0x68, 0xb6,
- 0xf7, 0x5d, 0x67, 0x5f, 0x42, 0xa4, 0xd8, 0xeb, 0xf7, 0x02, 0xa6, 0x09,
- 0xd7, 0x95, 0x24, 0x8e, 0xa0, 0x1e, 0x22, 0xa2, 0x7b, 0xfc, 0xeb, 0x89,
- 0xcf, 0xd5, 0x47, 0x5f, 0xd9, 0xd8, 0xf8, 0x5c, 0xeb, 0xff, 0xe8, 0x17,
- 0x45, 0x5a, 0x4d, 0x67, 0x32, 0x78, 0xeb, 0x32, 0x03, 0xfb, 0x9c, 0x57,
- 0x69, 0x9d, 0x51, 0x0e, 0x3f, 0x74, 0x8b, 0x83, 0x70, 0xcf, 0xf2, 0x4f,
- 0x30, 0xb0, 0xbf, 0x4f, 0xea, 0xdb, 0xd5, 0x1c, 0xeb, 0xf7, 0x65, 0x11,
- 0x23, 0x45, 0xd3, 0x7e, 0x71, 0x80, 0x39, 0xd7, 0x9f, 0xea, 0x8e, 0xbe,
- 0xc0, 0x60, 0x0e, 0xb4, 0xca, 0xc5, 0x19, 0x18, 0x68, 0x86, 0x7c, 0x24,
- 0x81, 0xdb, 0xff, 0xec, 0x1f, 0xa2, 0xf8, 0xe8, 0x31, 0xd5, 0x0e, 0xbf,
- 0xfc, 0xd7, 0xef, 0xbe, 0x35, 0xc7, 0x5c, 0x09, 0xd7, 0xf3, 0x61, 0xb0,
- 0x32, 0x3a, 0xff, 0xf6, 0x7d, 0xd8, 0xf3, 0xb6, 0xb1, 0x6e, 0xae, 0x75,
- 0xcb, 0x9b, 0x11, 0x8a, 0xca, 0x58, 0x95, 0xdf, 0x63, 0x0a, 0xd2, 0xce,
- 0xbf, 0xe4, 0xe8, 0xbe, 0xeb, 0x8f, 0x9d, 0x7f, 0xff, 0xc1, 0xeb, 0x75,
- 0xc8, 0x4e, 0xf7, 0xa1, 0xdd, 0x3b, 0x1a, 0x3a, 0xff, 0xc3, 0x0c, 0x7f,
- 0x39, 0x0c, 0xc1, 0xd7, 0xff, 0xf7, 0x04, 0x30, 0xaf, 0x8d, 0xe6, 0x29,
- 0x80, 0x64, 0x27, 0x5d, 0x2c, 0x3a, 0x9c, 0xfc, 0xd4, 0x5e, 0xbf, 0xf3,
- 0x73, 0xbd, 0x86, 0xed, 0x8c, 0x1d, 0x7f, 0xf6, 0x01, 0xda, 0xfd, 0x7f,
- 0x30, 0x27, 0x5f, 0xfa, 0x76, 0x35, 0x60, 0x49, 0xce, 0x03, 0xa9, 0x68,
- 0x83, 0x84, 0x2b, 0xa2, 0x6d, 0x95, 0x0e, 0xb2, 0xcf, 0xd8, 0x58, 0x7c,
- 0x8b, 0xcc, 0x30, 0xab, 0x8a, 0xae, 0x86, 0x52, 0xa5, 0xff, 0xbe, 0x92,
- 0x40, 0x40, 0xa8, 0xe7, 0x5f, 0xf3, 0xef, 0xc8, 0xd7, 0xdd, 0x83, 0xa9,
- 0xcf, 0xd7, 0xa7, 0x97, 0x07, 0x87, 0x5f, 0x87, 0x39, 0x1f, 0x3a, 0xfe,
- 0x6c, 0x64, 0xe7, 0x01, 0xd5, 0x3e, 0x9e, 0x92, 0xb7, 0x92, 0xdf, 0x20,
- 0x5a, 0xe7, 0x5f, 0xa1, 0x96, 0xa7, 0xce, 0xa6, 0x9e, 0x3f, 0xa4, 0x17,
- 0xff, 0xfc, 0xe0, 0xe6, 0x6f, 0xf1, 0x8e, 0x7b, 0x1a, 0xd4, 0x76, 0x47,
- 0x5f, 0xec, 0xcc, 0x51, 0x48, 0x69, 0xd4, 0xa2, 0x26, 0x3e, 0xcd, 0x7e,
- 0x9c, 0x9d, 0xc0, 0x1d, 0x7f, 0xfd, 0xae, 0x26, 0xbf, 0xcc, 0x02, 0x6b,
- 0x04, 0xeb, 0xdc, 0x71, 0xc3, 0xf5, 0x09, 0x45, 0xfe, 0x75, 0xe2, 0x2d,
- 0xd5, 0xce, 0xbf, 0xcd, 0x5e, 0x90, 0x77, 0x69, 0xd5, 0x23, 0xe6, 0x64,
- 0xce, 0xf4, 0x44, 0x8d, 0x12, 0x65, 0xe5, 0x49, 0xa3, 0xaa, 0x47, 0x88,
- 0xa8, 0x9e, 0xfd, 0x25, 0x63, 0x3f, 0xab, 0x53, 0xe9, 0xd7, 0xfb, 0x37,
- 0xff, 0xe1, 0xba, 0x3a, 0x9c, 0xfc, 0x3a, 0x7b, 0x7f, 0xff, 0x93, 0xb9,
- 0xea, 0x7a, 0xc6, 0x24, 0xe1, 0xcf, 0xf1, 0x0e, 0xa6, 0xaa, 0x14, 0xc8,
- 0x4b, 0xf5, 0x9d, 0x70, 0x94, 0xe1, 0x0d, 0xfc, 0x0f, 0x67, 0xdd, 0x7b,
- 0x3c, 0x75, 0xed, 0x20, 0x0e, 0xbf, 0x85, 0xf7, 0x5c, 0x7c, 0xeb, 0xfe,
- 0x79, 0x7c, 0x3c, 0xeb, 0xb0, 0x75, 0xff, 0x6f, 0x24, 0xee, 0x99, 0x78,
- 0x3a, 0xee, 0x23, 0x28, 0xb9, 0xe8, 0xda, 0xcb, 0x3e, 0x73, 0x7d, 0xf4,
- 0x5c, 0x1d, 0x7f, 0x93, 0x9a, 0x7f, 0xb8, 0x0e, 0xac, 0x3d, 0x1f, 0x90,
- 0x5f, 0xf3, 0xf3, 0xe9, 0xb2, 0xde, 0x47, 0x5f, 0xff, 0xa2, 0x5d, 0x7e,
- 0x0e, 0x7f, 0x26, 0x61, 0x86, 0x0a, 0xa6, 0xa2, 0xc3, 0x44, 0x3f, 0x38,
- 0xbf, 0xa5, 0x20, 0xc8, 0x5c, 0xeb, 0xff, 0x47, 0xdf, 0xba, 0xe3, 0x8f,
- 0xce, 0xbf, 0x63, 0x52, 0x27, 0x1d, 0x60, 0x89, 0xf1, 0xe8, 0xf2, 0xff,
- 0xfe, 0x9c, 0x9c, 0x17, 0x6f, 0x7a, 0x1d, 0xd3, 0xb1, 0xa3, 0xaf, 0x95,
- 0x3f, 0x34, 0x75, 0x39, 0xff, 0xe2, 0xe5, 0xfa, 0x1b, 0xe7, 0x19, 0x3a,
- 0xff, 0xf3, 0xec, 0x39, 0x9b, 0x7d, 0x47, 0x16, 0x9d, 0x7f, 0xe8, 0x1d,
- 0xb9, 0x0b, 0x4d, 0x21, 0xd4, 0x28, 0x85, 0x61, 0x26, 0xf3, 0x0c, 0x30,
- 0x55, 0xf6, 0xcb, 0x4d, 0x15, 0x31, 0x7f, 0x73, 0x80, 0xeb, 0x76, 0x0f,
- 0x1c, 0x4c, 0xaf, 0xf3, 0x5f, 0xbb, 0x3f, 0x76, 0x3a, 0xfe, 0xd6, 0x93,
- 0x07, 0xd3, 0xaf, 0x77, 0x15, 0xce, 0xbf, 0xf3, 0xb1, 0xe7, 0x6d, 0x62,
- 0xdd, 0x5c, 0xea, 0xea, 0x23, 0x96, 0x59, 0xf1, 0xea, 0x74, 0x79, 0x64,
- 0x30, 0xaf, 0xc9, 0xfd, 0xb1, 0x83, 0xaf, 0xf9, 0xe5, 0xc1, 0x0f, 0xdf,
- 0x47, 0x5f, 0xff, 0xbf, 0xcc, 0x6f, 0x89, 0x71, 0x3f, 0xbc, 0x93, 0xa7,
- 0x57, 0x51, 0x6e, 0xb2, 0x81, 0x37, 0xbf, 0xe5, 0xbf, 0x67, 0x67, 0x5d,
- 0x93, 0xaf, 0xfd, 0xd9, 0x2d, 0xf7, 0xd6, 0x4e, 0xc3, 0xaf, 0xe1, 0xf1,
- 0x3d, 0x9d, 0x73, 0xa9, 0xcf, 0xc2, 0x10, 0x2f, 0xfb, 0x23, 0xdf, 0x18,
- 0x08, 0x69, 0xd7, 0xfd, 0xe0, 0x7c, 0x6b, 0x68, 0x8e, 0x1d, 0x7f, 0xfa,
- 0x36, 0xe2, 0x38, 0xe3, 0x29, 0xd4, 0x3a, 0xb1, 0x3b, 0x5f, 0x4b, 0xf5,
- 0x0a, 0xaf, 0x90, 0x04, 0xe5, 0x83, 0xcb, 0xf0, 0xe7, 0x23, 0xe7, 0x5f,
- 0xf9, 0xae, 0x3b, 0x79, 0xe8, 0x85, 0xa7, 0x52, 0xb9, 0xf2, 0xb2, 0x4b,
- 0x7d, 0xfd, 0xb0, 0x07, 0x5f, 0xf2, 0x29, 0xe7, 0xbe, 0xad, 0x34, 0x75,
- 0x32, 0x7b, 0xd3, 0xc4, 0x57, 0x98, 0x61, 0x83, 0xaf, 0xff, 0xd8, 0xbf,
- 0x8b, 0xfb, 0x80, 0xd6, 0x2d, 0xe4, 0x54, 0xc5, 0xfd, 0xfe, 0xeb, 0xfd,
- 0x24, 0x80, 0x3a, 0xdd, 0x3a, 0x95, 0x93, 0xc1, 0xf2, 0x63, 0x58, 0x9c,
- 0xb2, 0x42, 0x13, 0x88, 0xba, 0x85, 0x25, 0xef, 0xb7, 0x87, 0x59, 0x0e,
- 0xbf, 0xb8, 0xfe, 0x24, 0x9b, 0x1d, 0x7f, 0x76, 0x3a, 0x2e, 0xd3, 0xaf,
- 0xff, 0xa3, 0xfc, 0xc9, 0xdc, 0x4f, 0x1a, 0xd2, 0x2c, 0xeb, 0xff, 0x23,
- 0x53, 0xbb, 0xb8, 0xbe, 0x8e, 0xa5, 0x6c, 0x8f, 0x70, 0x07, 0xf4, 0xbc,
- 0x4a, 0xfe, 0xa5, 0x73, 0x66, 0x9f, 0x1b, 0x13, 0xc9, 0xfd, 0xa1, 0xdd,
- 0x5b, 0x0b, 0xbc, 0x95, 0x5a, 0xa2, 0xac, 0xa1, 0xe3, 0xbc, 0x69, 0x48,
- 0x60, 0xcc, 0x23, 0xfb, 0x0a, 0x65, 0x90, 0x72, 0x15, 0xd1, 0x08, 0x91,
- 0x8c, 0x63, 0x52, 0xa4, 0xbf, 0x29, 0x66, 0x79, 0x1b, 0xcc, 0x62, 0x77,
- 0xff, 0xbb, 0x8c, 0x03, 0x98, 0xc8, 0xe7, 0x5a, 0x75, 0xee, 0xe2, 0xb9,
- 0xd7, 0xfe, 0x76, 0x3c, 0xed, 0xac, 0x5b, 0xab, 0x9d, 0x5d, 0x45, 0x62,
- 0xd2, 0xbe, 0x3d, 0x7f, 0xfd, 0x0b, 0x7e, 0xcb, 0xa1, 0x53, 0xa1, 0x8d,
- 0x1d, 0x58, 0x88, 0x00, 0x98, 0x5f, 0xee, 0xc8, 0x30, 0x05, 0xb9, 0xd7,
- 0xff, 0x3f, 0x7c, 0xfd, 0x3f, 0xcc, 0x02, 0x1d, 0x7f, 0xee, 0x0b, 0xed,
- 0xe7, 0x9c, 0x85, 0x73, 0xa9, 0xd1, 0x73, 0xb1, 0x96, 0x22, 0x5f, 0xd1,
- 0x29, 0x98, 0x61, 0x83, 0xaf, 0xe7, 0xec, 0x35, 0x38, 0x75, 0xfb, 0x17,
- 0xc8, 0x01, 0xd6, 0x99, 0xdb, 0xa4, 0x7c, 0x8c, 0x45, 0x43, 0xc9, 0x4a,
- 0xe1, 0xec, 0x28, 0x22, 0xb1, 0x5d, 0x19, 0x52, 0x1a, 0x86, 0xdc, 0xe2,
- 0xf6, 0x0c, 0x55, 0x15, 0xd3, 0x5d, 0x36, 0x28, 0x27, 0x14, 0xf7, 0x8c,
- 0x6f, 0xa5, 0x0b, 0x84, 0x57, 0x21, 0x97, 0xec, 0x29, 0xb5, 0x2a, 0x4b,
- 0xf1, 0x9c, 0x86, 0xba, 0x9b, 0xbf, 0xb4, 0xec, 0xb5, 0x19, 0x3a, 0xff,
- 0xf3, 0xed, 0x9f, 0x71, 0x4f, 0x73, 0x7f, 0x9d, 0x69, 0xb4, 0x7e, 0xfe,
- 0x4b, 0xaf, 0xdd, 0x94, 0x44, 0x8d, 0x11, 0xad, 0xe5, 0x37, 0xd1, 0xd6,
- 0x9b, 0x0f, 0x47, 0xe6, 0x77, 0xee, 0xca, 0x22, 0x46, 0x8a, 0x96, 0xe8,
- 0x91, 0xa2, 0x1a, 0xb4, 0xd8, 0x7a, 0xb0, 0x67, 0x7e, 0xec, 0xa2, 0x24,
- 0x68, 0x8f, 0xaf, 0xff, 0x86, 0x3e, 0xd7, 0x53, 0xc3, 0xff, 0x4f, 0xe9,
- 0xd7, 0xa1, 0xb3, 0x62, 0x21, 0x3c, 0x99, 0xdf, 0xfe, 0x5e, 0x4d, 0xe5,
- 0xfb, 0x83, 0xfc, 0xe1, 0xd5, 0x32, 0x20, 0x1c, 0xda, 0xff, 0xff, 0x9a,
- 0x1e, 0xa9, 0x1a, 0xc0, 0x3e, 0xfa, 0xf3, 0xf5, 0x11, 0x43, 0xaf, 0xe0,
- 0xef, 0xbb, 0x73, 0xe7, 0x5f, 0xbb, 0x28, 0x89, 0x1a, 0x2c, 0x7b, 0xa3,
- 0x47, 0x5f, 0xdb, 0x79, 0xef, 0x73, 0xa7, 0x53, 0x4f, 0x16, 0x05, 0x6f,
- 0xf8, 0x61, 0x4e, 0x23, 0x8e, 0xc7, 0x5f, 0xd8, 0x9f, 0xfa, 0x7c, 0xeb,
- 0xf6, 0x77, 0x31, 0x93, 0xad, 0x33, 0xa7, 0x79, 0xb3, 0x66, 0x17, 0xa3,
- 0xc3, 0x24, 0x3a, 0x37, 0xf2, 0x57, 0x79, 0x58, 0xad, 0x43, 0xaf, 0xe9,
- 0xf4, 0x73, 0x91, 0xf3, 0xaf, 0xf8, 0x63, 0xdd, 0x47, 0xff, 0x07, 0x5f,
- 0xfb, 0x18, 0xee, 0x0c, 0x6e, 0xdd, 0x1d, 0x7e, 0xcd, 0x71, 0x18, 0x3a,
- 0xfb, 0xd5, 0xa7, 0x4e, 0xbf, 0xff, 0xe7, 0xe8, 0xe0, 0x33, 0x9c, 0x49,
- 0x71, 0x3f, 0xa8, 0xdc, 0xea, 0x44, 0x43, 0x70, 0x8a, 0xfe, 0x7e, 0xfb,
- 0x3c, 0x1f, 0x9d, 0x7f, 0xce, 0x3f, 0x9f, 0xe3, 0xe1, 0x73, 0xaf, 0xff,
- 0x3f, 0x1d, 0x72, 0xe2, 0x7f, 0x31, 0x67, 0x5e, 0x88, 0x91, 0xa2, 0xd0,
- 0xbf, 0xf4, 0x30, 0xaa, 0x51, 0xdd, 0xb1, 0x83, 0xaf, 0xef, 0x5c, 0x5f,
- 0xfa, 0x3a, 0xa4, 0x89, 0x5e, 0x93, 0xfa, 0x85, 0x7f, 0xff, 0xfc, 0x9d,
- 0xe4, 0x0a, 0x3f, 0xd3, 0x8f, 0xae, 0x66, 0xbb, 0x92, 0xcf, 0x9d, 0x4d,
- 0x4f, 0xc4, 0x06, 0x32, 0x3b, 0xec, 0x37, 0x38, 0x63, 0x7f, 0xfa, 0x23,
- 0x79, 0xdc, 0x57, 0x4f, 0x8b, 0xac, 0xeb, 0xff, 0xf2, 0x7f, 0x51, 0xbe,
- 0xb5, 0x9c, 0x4d, 0x07, 0x63, 0xaf, 0xff, 0x83, 0xb7, 0x53, 0xfb, 0x07,
- 0xad, 0xd2, 0xba, 0x1d, 0x5c, 0x45, 0x58, 0xab, 0x5f, 0xff, 0x07, 0xbd,
- 0x71, 0xc5, 0x13, 0x9c, 0xcf, 0x27, 0x5a, 0x7e, 0x3a, 0xdd, 0xe9, 0xf2,
- 0x85, 0x42, 0xfc, 0x32, 0x8d, 0x21, 0xd7, 0xff, 0xf7, 0x45, 0xdf, 0x7f,
- 0x1a, 0xf8, 0xb8, 0x38, 0xff, 0x3a, 0xe4, 0xe1, 0xd7, 0xcd, 0x18, 0xf2,
- 0x75, 0xff, 0x20, 0x23, 0xde, 0xf6, 0x3d, 0x3a, 0x9d, 0x1e, 0x18, 0x4a,
- 0xae, 0xb7, 0x02, 0xa1, 0x22, 0xbd, 0x0a, 0xe8, 0x75, 0xff, 0xbc, 0xfd,
- 0x44, 0x51, 0xf0, 0x5c, 0xeb, 0xf7, 0x9f, 0x8b, 0xfa, 0x75, 0x6e, 0x88,
- 0x5e, 0x8e, 0xce, 0x3f, 0xbf, 0x3f, 0xf3, 0x8e, 0x75, 0xff, 0xff, 0xee,
- 0x20, 0x31, 0x36, 0xe3, 0xbf, 0x8c, 0xdd, 0xba, 0x4f, 0xc0, 0xe1, 0xd7,
- 0xfe, 0xcd, 0xdb, 0xa6, 0x7b, 0x1f, 0xd1, 0xd7, 0xff, 0xd9, 0xfd, 0x63,
- 0x3c, 0x79, 0xd9, 0xce, 0x39, 0xd7, 0xfc, 0x2e, 0xec, 0xe4, 0xe4, 0xe9,
- 0xd5, 0xb2, 0x6c, 0x72, 0x25, 0xf5, 0xd8, 0x50, 0x3e, 0xa1, 0x7e, 0xf0,
- 0xcb, 0x51, 0x93, 0xa9, 0xd5, 0x06, 0xe4, 0x72, 0xc8, 0x99, 0x7f, 0xff,
- 0xdf, 0xe3, 0x8e, 0x7b, 0xac, 0x07, 0x1f, 0x65, 0x84, 0x40, 0x75, 0xff,
- 0xfc, 0xec, 0xe0, 0x38, 0xf3, 0xb9, 0x9f, 0x17, 0x75, 0x9d, 0x7f, 0x6f,
- 0xaf, 0x3b, 0x04, 0x4e, 0xbf, 0xe7, 0x97, 0x11, 0x98, 0x8d, 0x8e, 0xa5,
- 0xa3, 0x0e, 0x16, 0xbd, 0x31, 0xbf, 0xcd, 0x7e, 0xec, 0xfd, 0xd8, 0xeb,
- 0xfe, 0x40, 0x8b, 0x7a, 0xf8, 0x03, 0xaf, 0xff, 0xfb, 0x98, 0xd9, 0x71,
- 0x38, 0xf9, 0xd6, 0xfc, 0x5d, 0x7a, 0x3a, 0xb4, 0x89, 0xaf, 0x9b, 0x53,
- 0xa3, 0xc7, 0x21, 0x9d, 0x7f, 0xbb, 0x26, 0x71, 0x38, 0x13, 0xaf, 0xf2,
- 0xde, 0x43, 0x1b, 0xfc, 0xeb, 0xfb, 0xaf, 0xfd, 0xb1, 0x83, 0xaf, 0xff,
- 0xff, 0x90, 0x3d, 0xe6, 0x32, 0xcc, 0x75, 0x9f, 0xf0, 0x3e, 0xeb, 0x12,
- 0x70, 0x1c, 0xeb, 0xf7, 0xf9, 0x02, 0xa1, 0xd7, 0xfc, 0x21, 0xd8, 0x1c,
- 0xc1, 0x73, 0xad, 0x80, 0x47, 0x06, 0x42, 0x0a, 0x44, 0xf7, 0xff, 0xbb,
- 0xec, 0xbd, 0x1c, 0xfe, 0xa2, 0x04, 0xea, 0x74, 0xfd, 0x70, 0xcd, 0x0c,
- 0x86, 0x30, 0xe0, 0x9c, 0xdf, 0xec, 0xe3, 0x29, 0xc4, 0x59, 0xd7, 0xf9,
- 0xb9, 0xdd, 0x0b, 0xec, 0x75, 0xec, 0xe4, 0x1d, 0x7e, 0x64, 0x01, 0x08,
- 0x9d, 0x40, 0x3c, 0x28, 0x1a, 0xbf, 0xd8, 0xc6, 0x4a, 0x58, 0xc1, 0xd7,
- 0x94, 0x68, 0x4e, 0xbf, 0x71, 0xfb, 0xb2, 0xce, 0xbf, 0xc1, 0x81, 0xe6,
- 0x43, 0x27, 0x5b, 0x76, 0x4f, 0x65, 0x82, 0x8a, 0x44, 0x50, 0xc3, 0xb5,
- 0x62, 0x3d, 0x46, 0x1a, 0x95, 0x89, 0xf1, 0x6e, 0x65, 0x0e, 0x9a, 0x8c,
- 0x5a, 0xef, 0xb9, 0xd7, 0x47, 0xce, 0xb6, 0x74, 0xd5, 0x70, 0x56, 0xfe,
- 0x41, 0x0b, 0x73, 0x47, 0x5f, 0xfb, 0x3e, 0xfb, 0xfb, 0x1c, 0xe2, 0x1d,
- 0x65, 0x9d, 0x7f, 0x20, 0x85, 0xb9, 0xaf, 0x07, 0x9d, 0x38, 0xfa, 0x94,
- 0x46, 0x07, 0xde, 0x6d, 0x34, 0xf8, 0xd8, 0xc5, 0xcf, 0xe4, 0x6e, 0x61,
- 0xb1, 0xbb, 0x4f, 0x81, 0x0a, 0xdc, 0x94, 0x26, 0xa2, 0x84, 0xa1, 0xf0,
- 0x90, 0x87, 0x5c, 0x63, 0x1c, 0x95, 0xb9, 0x06, 0xbe, 0xc6, 0x52, 0x31,
- 0x90, 0xea, 0x50, 0xdf, 0xe5, 0x17, 0xcf, 0x36, 0xf9, 0x87, 0x35, 0xfc,
- 0xa9, 0x00, 0x2e, 0xc9, 0xd7, 0x9e, 0x04, 0xeb, 0xec, 0xe4, 0x7c, 0xeb,
- 0x4f, 0xb8, 0x7c, 0xfc, 0x2e, 0x11, 0x9b, 0xcb, 0xd2, 0x87, 0x5f, 0x66,
- 0xbd, 0x43, 0xaf, 0xdd, 0x94, 0x44, 0x8d, 0x16, 0xb5, 0xfd, 0x8a, 0xb5,
- 0x03, 0x23, 0xaf, 0x75, 0xd6, 0x75, 0xfd, 0xcc, 0xd3, 0xec, 0xa8, 0xeb,
- 0xfe, 0x6c, 0xd9, 0xd9, 0x44, 0x48, 0xd1, 0x41, 0xd6, 0x1f, 0xa4, 0x17,
- 0xdf, 0x63, 0x2f, 0xf3, 0xaf, 0xf9, 0xda, 0xfd, 0xd9, 0xfb, 0xb1, 0xd7,
- 0xff, 0xef, 0xe9, 0x36, 0x8d, 0x40, 0xc7, 0xf8, 0xec, 0x9d, 0x69, 0xa7,
- 0xf5, 0x46, 0x6e, 0x70, 0xd1, 0xdc, 0x21, 0x64, 0xcf, 0xa5, 0xab, 0x84,
- 0x7f, 0x08, 0x04, 0x87, 0xc9, 0xcd, 0xff, 0xe9, 0x97, 0x0d, 0x9b, 0x3b,
- 0x28, 0x89, 0x1a, 0x28, 0xbb, 0xfd, 0x36, 0x76, 0x51, 0x12, 0x34, 0x5d,
- 0x54, 0xed, 0xd9, 0x23, 0x5f, 0x24, 0xfa, 0x91, 0x95, 0xae, 0x3d, 0xfe,
- 0x56, 0x3f, 0x1e, 0xcb, 0xf5, 0xd4, 0x27, 0xbe, 0xaf, 0x7e, 0xec, 0xa2,
- 0x24, 0x68, 0x88, 0x6f, 0x73, 0x00, 0x75, 0xf6, 0x4e, 0x4e, 0x9d, 0x69,
- 0xb0, 0xfc, 0x37, 0x33, 0x57, 0x1b, 0xbe, 0x7e, 0x3a, 0xce, 0xbe, 0x94,
- 0x44, 0x8d, 0x11, 0xb5, 0xd3, 0x64, 0x8f, 0x37, 0xa4, 0x17, 0xfa, 0x6c,
- 0xec, 0xa2, 0x24, 0x68, 0xa6, 0xef, 0xdd, 0x94, 0x44, 0x8d, 0x15, 0x05,
- 0xec, 0xdd, 0x83, 0xad, 0x36, 0x1e, 0x87, 0x0c, 0xef, 0xf4, 0xd9, 0xd9,
- 0x44, 0x48, 0xd1, 0x53, 0x5f, 0xbb, 0x28, 0x89, 0x1a, 0x2b, 0x0b, 0xf2,
- 0x30, 0x00, 0xf4, 0xeb, 0xfe, 0x6c, 0xd9, 0xd9, 0x44, 0x48, 0xd1, 0x1f,
- 0xde, 0xc7, 0xd8, 0xeb, 0xfd, 0x9b, 0xb6, 0x1a, 0x82, 0x75, 0xd1, 0xf3,
- 0xad, 0x36, 0x26, 0x03, 0x23, 0x38, 0x28, 0x14, 0x5f, 0x8d, 0xcf, 0x18,
- 0xdf, 0xfe, 0x99, 0x70, 0xd9, 0xb3, 0xb2, 0x88, 0x91, 0xa2, 0x6f, 0xbf,
- 0xf9, 0x70, 0xd9, 0xb3, 0xb2, 0x88, 0x91, 0xa2, 0x7e, 0xb8, 0x64, 0x75,
- 0xfe, 0x97, 0x13, 0xf9, 0x8b, 0x3a, 0xe9, 0xd2, 0x3c, 0x60, 0x54, 0xe7,
- 0xd7, 0xa1, 0x5f, 0x98, 0xdf, 0xe5, 0x60, 0xac, 0x8e, 0x6c, 0xfb, 0x9d,
- 0x7e, 0x56, 0xa7, 0xd9, 0xec, 0xdc, 0xeb, 0xf4, 0xf8, 0xa2, 0x98, 0xae,
- 0x75, 0xd3, 0xa4, 0x78, 0xc0, 0x6d, 0xc3, 0xa9, 0x5a, 0x46, 0xca, 0xb2,
- 0x7c, 0xac, 0x0d, 0x7e, 0x62, 0x12, 0x5b, 0xfe, 0x56, 0x1c, 0x8f, 0xfe,
- 0x21, 0x83, 0xaf, 0xff, 0xf2, 0xb5, 0x3e, 0xeb, 0xae, 0x9f, 0xe6, 0x01,
- 0x35, 0x83, 0xe9, 0xd7, 0xee, 0x24, 0x7a, 0xac, 0x0e, 0xa5, 0x65, 0x12,
- 0xdf, 0x69, 0xbf, 0x4f, 0xea, 0xdb, 0xd5, 0x1c, 0xeb, 0xff, 0xe7, 0x77,
- 0x77, 0x77, 0x77, 0x7d, 0xf4, 0x75, 0xfb, 0xa9, 0xb4, 0x2c, 0xab, 0x98,
- 0x60, 0xaa, 0xc3, 0x7e, 0xc1, 0x3d, 0x82, 0x54, 0xc6, 0x86, 0x9d, 0x19,
- 0x5a, 0x85, 0x4d, 0xfa, 0x20, 0x5d, 0x51, 0xd7, 0xff, 0x71, 0xd3, 0xa1,
- 0x10, 0xfc, 0x3f, 0x3a, 0xf0, 0xa3, 0x9d, 0x7e, 0x7f, 0x2b, 0xe2, 0x1d,
- 0x5d, 0x3c, 0x11, 0x19, 0xbf, 0x9b, 0xaf, 0xe0, 0xa8, 0x75, 0xe6, 0x21,
- 0x83, 0xaf, 0xff, 0x7f, 0xb1, 0xb0, 0x38, 0xfa, 0xf8, 0x78, 0x75, 0xd8,
- 0xbe, 0x1f, 0x46, 0x87, 0x6f, 0xd1, 0x2e, 0x27, 0x4e, 0xbf, 0xff, 0xfc,
- 0x30, 0xa2, 0x75, 0xdb, 0xe3, 0x88, 0xb0, 0x3f, 0x89, 0xe0, 0xf1, 0x3a,
- 0x75, 0xf4, 0x35, 0x37, 0x3a, 0xff, 0xdc, 0x4f, 0xe7, 0x7a, 0x1d, 0xa7,
- 0x1d, 0x7f, 0xc9, 0xfc, 0xef, 0x43, 0xb4, 0xe3, 0xaf, 0x68, 0x23, 0xe0,
- 0xff, 0x38, 0x83, 0x40, 0x4e, 0x8b, 0xa5, 0xbc, 0x26, 0x17, 0xdd, 0x42,
- 0x76, 0xce, 0x75, 0xff, 0xf3, 0xee, 0xd8, 0x1f, 0x7c, 0x7a, 0x9d, 0x45,
- 0x0e, 0xa9, 0xe3, 0xe2, 0x54, 0x1f, 0x7d, 0xb2, 0xd1, 0xa7, 0x5f, 0xb4,
- 0x21, 0x86, 0x9d, 0x7f, 0xb8, 0xeb, 0x9b, 0xdf, 0x5c, 0xea, 0x73, 0xfd,
- 0xc2, 0x24, 0x26, 0xbf, 0x99, 0x4e, 0x7f, 0x24, 0x75, 0x74, 0xf6, 0x60,
- 0xb2, 0xff, 0xb7, 0x07, 0x97, 0x57, 0xe0, 0x74, 0x75, 0xff, 0xf8, 0x1c,
- 0x7e, 0xa7, 0xaf, 0xe5, 0xd9, 0x17, 0x59, 0xd7, 0xf9, 0x47, 0x1f, 0xea,
- 0x38, 0x75, 0x22, 0x22, 0x21, 0x5a, 0x9d, 0x1d, 0x03, 0x0c, 0x7b, 0xfe,
- 0x7e, 0x3e, 0xdd, 0x7c, 0x01, 0xd7, 0xfd, 0xbe, 0xb9, 0x1e, 0x78, 0xed,
- 0x3a, 0xf6, 0x63, 0x27, 0x59, 0x5c, 0xeb, 0xdf, 0x6e, 0x1d, 0x76, 0xb0,
- 0xeb, 0xff, 0xb4, 0xfd, 0x97, 0xc7, 0x36, 0x81, 0x3a, 0x91, 0x10, 0xb0,
- 0x27, 0xe8, 0xdf, 0xc5, 0x6f, 0xfe, 0x03, 0xfe, 0x35, 0x9c, 0xe2, 0x2c,
- 0xeb, 0xdf, 0x46, 0x4e, 0xa7, 0x3d, 0xed, 0x21, 0x5f, 0x9d, 0x5d, 0x18,
- 0x91, 0xd4, 0xeb, 0xff, 0xbb, 0x13, 0x80, 0x9b, 0x21, 0x09, 0xb9, 0x0a,
- 0x4a, 0x37, 0x66, 0x16, 0x3d, 0x87, 0xea, 0xe3, 0x09, 0xe1, 0x34, 0x1b,
- 0xfa, 0x76, 0x30, 0xa0, 0xfc, 0x26, 0xbc, 0x90, 0xdf, 0xff, 0xf2, 0xb7,
- 0xcf, 0xef, 0x8a, 0xdd, 0xd9, 0xfd, 0x58, 0xce, 0x57, 0x56, 0x01, 0xf1,
- 0xe3, 0x93, 0xc7, 0x5e, 0x67, 0xca, 0xce, 0xbf, 0xec, 0xfe, 0xb3, 0xfc,
- 0xcf, 0x4e, 0xa8, 0x3d, 0x71, 0x1f, 0xba, 0x04, 0xea, 0xe9, 0xb4, 0x59,
- 0x05, 0xf3, 0xff, 0x16, 0x75, 0xfb, 0xee, 0x29, 0xe9, 0xd5, 0xe0, 0xf1,
- 0xb0, 0x82, 0xff, 0x77, 0x3b, 0xb3, 0xff, 0x47, 0x5e, 0x61, 0x86, 0x0e,
- 0xbe, 0xd8, 0x51, 0xca, 0x98, 0xbf, 0xbb, 0x76, 0x9d, 0x7f, 0x94, 0x7f,
- 0xeb, 0x90, 0x13, 0xaf, 0xc9, 0xb6, 0x6f, 0xf3, 0xae, 0x49, 0x1d, 0x6d,
- 0xdd, 0x10, 0xea, 0x0b, 0xac, 0xcf, 0xe5, 0x14, 0xac, 0x55, 0x7d, 0x3c,
- 0x64, 0x60, 0x67, 0x42, 0x3e, 0x29, 0x06, 0x16, 0xf7, 0xff, 0x4e, 0x63,
- 0x34, 0x28, 0xfd, 0xcd, 0x8e, 0xbf, 0xf6, 0xa1, 0x4e, 0x23, 0x88, 0x5c,
- 0xeb, 0xf4, 0x74, 0x31, 0xa3, 0xae, 0x6f, 0xce, 0xbe, 0x65, 0xff, 0x07,
- 0x5f, 0xb6, 0x0f, 0xb8, 0x32, 0x36, 0xe1, 0x16, 0xbf, 0xf9, 0xf9, 0xe4,
- 0x1f, 0x4c, 0x65, 0xd6, 0x75, 0xf3, 0xfc, 0x2b, 0x3a, 0xed, 0x48, 0xd1,
- 0x07, 0x52, 0xcf, 0x13, 0xe4, 0x37, 0xff, 0xe5, 0xea, 0x1b, 0xc4, 0xcf,
- 0xeb, 0xb8, 0x0c, 0x3a, 0xff, 0x9f, 0xe3, 0x93, 0x87, 0x34, 0x75, 0x3a,
- 0x2b, 0x30, 0x8b, 0x4a, 0x77, 0xf4, 0x71, 0xd5, 0xc2, 0xd3, 0xaa, 0x4a,
- 0x8b, 0xba, 0xba, 0xb3, 0xff, 0xc6, 0x6b, 0x38, 0xba, 0xff, 0x3b, 0x47,
- 0x37, 0xfe, 0x1d, 0x7f, 0xa0, 0x7e, 0xdc, 0xee, 0x1d, 0x77, 0x40, 0x75,
- 0xcc, 0x30, 0x75, 0x34, 0xd7, 0x30, 0x2d, 0x7d, 0xa7, 0x49, 0xc5, 0x4c,
- 0x68, 0xae, 0xf7, 0x47, 0x5f, 0xc9, 0xc4, 0x51, 0x47, 0x3a, 0xed, 0x79,
- 0x01, 0xe2, 0x7c, 0x5e, 0x91, 0x14, 0xfe, 0x5d, 0xef, 0x30, 0xc3, 0x05,
- 0x51, 0x53, 0x17, 0xf7, 0xc8, 0xc2, 0x32, 0x55, 0x48, 0xde, 0x20, 0xd5,
- 0xfb, 0x3a, 0xf3, 0xb0, 0xea, 0x75, 0xd2, 0x1c, 0x45, 0x49, 0x4d, 0x5d,
- 0x54, 0x59, 0x8f, 0x23, 0x27, 0x17, 0xfd, 0x10, 0x5f, 0xe1, 0xdf, 0xfe,
- 0x79, 0x1e, 0x9d, 0x78, 0x53, 0x47, 0x5f, 0x02, 0x07, 0xd3, 0xaf, 0xfe,
- 0x71, 0xf4, 0x5f, 0x76, 0x5c, 0x7d, 0x3a, 0xb1, 0x16, 0xa8, 0x6d, 0xe8,
- 0xd6, 0x88, 0x6c, 0x87, 0x5f, 0x6d, 0xb4, 0x6e, 0x75, 0xde, 0xe9, 0x0d,
- 0x9f, 0x90, 0xfb, 0xf3, 0xe7, 0x78, 0x87, 0x5f, 0xfe, 0x63, 0xde, 0x66,
- 0x6c, 0x99, 0x39, 0xf7, 0x3a, 0xff, 0xf7, 0xae, 0xbe, 0xf5, 0xf6, 0xfc,
- 0x42, 0x87, 0x5e, 0xc5, 0xab, 0x9d, 0x7f, 0xb3, 0x43, 0x9f, 0xe2, 0x1d,
- 0x40, 0x3c, 0xe1, 0x1e, 0xac, 0x4d, 0x6d, 0x92, 0xfe, 0x12, 0xfa, 0x9b,
- 0x3a, 0x13, 0x37, 0xf7, 0xf1, 0x91, 0x75, 0x9e, 0x20, 0x2b, 0xf4, 0x08,
- 0x38, 0xe6, 0x88, 0x0a, 0x63, 0x73, 0x7f, 0xf2, 0x6f, 0xa0, 0x60, 0xb8,
- 0x85, 0xce, 0xbf, 0xf8, 0x32, 0x53, 0xb9, 0xbe, 0xbd, 0x8f, 0x9d, 0x7e,
- 0x76, 0xc6, 0xec, 0x1d, 0x58, 0x8b, 0x04, 0x41, 0xea, 0x3d, 0xfe, 0xee,
- 0xde, 0x31, 0x94, 0x59, 0xd7, 0xfe, 0x41, 0x53, 0xa2, 0x92, 0x08, 0x9d,
- 0x4e, 0x7e, 0x58, 0x6d, 0x7c, 0xb7, 0xc5, 0x9d, 0x7f, 0xec, 0x5b, 0xc9,
- 0x3f, 0xd0, 0xac, 0xeb, 0xc9, 0xbe, 0x8e, 0xb3, 0xb4, 0xf6, 0x7d, 0x3d,
- 0xbf, 0xdd, 0x67, 0x48, 0x3f, 0x43, 0xaf, 0xb7, 0xf7, 0xae, 0x55, 0xcc,
- 0x30, 0x55, 0x39, 0xbb, 0x60, 0x8e, 0xfe, 0x8e, 0xb5, 0xa2, 0x85, 0x4c,
- 0x68, 0x69, 0xd7, 0x5d, 0x32, 0x3c, 0xa4, 0x84, 0x67, 0x61, 0xe7, 0xc8,
- 0x50, 0x41, 0x00, 0xbc, 0xfc, 0xa0, 0x30, 0x8e, 0xbd, 0xb4, 0x2c, 0xeb,
- 0xef, 0x86, 0x3c, 0x9a, 0x20, 0x7a, 0x83, 0xcc, 0x08, 0xe5, 0xe5, 0x74,
- 0xf4, 0xeb, 0x9c, 0x27, 0x5f, 0x82, 0x3e, 0xf9, 0x69, 0xd7, 0xff, 0xc3,
- 0x9a, 0xf1, 0xe7, 0x8f, 0xea, 0xe1, 0xbe, 0x30, 0xdf, 0xe8, 0x56, 0x82,
- 0x8c, 0x99, 0xcb, 0xd7, 0xfe, 0xe0, 0x76, 0x7f, 0x0f, 0xf7, 0x01, 0xd7,
- 0xa3, 0xbb, 0x1d, 0x73, 0x0c, 0x1d, 0x7f, 0xba, 0x99, 0x3b, 0xcb, 0x66,
- 0x91, 0xb4, 0x60, 0x72, 0x80, 0x8c, 0x3e, 0xba, 0x5f, 0xfc, 0x38, 0xa7,
- 0x21, 0xbe, 0x63, 0x77, 0x3a, 0x9c, 0xfa, 0x30, 0x8e, 0xff, 0xe5, 0xae,
- 0x1b, 0x9d, 0x94, 0x44, 0x8d, 0x10, 0xc5, 0xff, 0xff, 0xe8, 0xd6, 0x0e,
- 0x4b, 0x8f, 0xbb, 0x67, 0xb3, 0x92, 0x4c, 0x18, 0x50, 0xea, 0xc4, 0x63,
- 0x05, 0x3e, 0x91, 0x52, 0xc7, 0x23, 0x50, 0x18, 0x73, 0x5f, 0xe5, 0xf2,
- 0x36, 0x17, 0x69, 0xd7, 0xfc, 0xfb, 0xb7, 0x91, 0x02, 0xe7, 0x5f, 0xbb,
- 0x28, 0x89, 0x1a, 0x20, 0xab, 0xdc, 0x75, 0x9d, 0x7f, 0xe7, 0xda, 0x3f,
- 0xdc, 0x6c, 0xf6, 0x1d, 0x58, 0x88, 0xe4, 0x33, 0x11, 0xbb, 0xef, 0xe9,
- 0xfd, 0x2a, 0xf4, 0x77, 0x62, 0xaf, 0x82, 0x30, 0xa1, 0x57, 0xf9, 0x36,
- 0xcf, 0xe9, 0xfd, 0x2a, 0x8a, 0xbf, 0xb2, 0x4f, 0xc7, 0x59, 0x57, 0x30,
- 0xc1, 0x57, 0xf0, 0xb8, 0xec, 0x9d, 0x2a, 0xb1, 0x30, 0xa9, 0x11, 0x2c,
- 0x73, 0x84, 0x3e, 0x99, 0x88, 0x53, 0x05, 0x7e, 0x46, 0x2e, 0x4e, 0x95,
- 0x31, 0xfa, 0x53, 0x53, 0xd2, 0xe4, 0x75, 0x74, 0xea, 0xbc, 0xb8, 0x65,
- 0x12, 0xa5, 0xaf, 0xf7, 0x30, 0x74, 0x83, 0x87, 0x5f, 0xe8, 0x1c, 0xd7,
- 0x5f, 0x47, 0x5f, 0xc0, 0xc1, 0x8f, 0xe8, 0xeb, 0x3b, 0x4f, 0x6f, 0x46,
- 0x17, 0xee, 0xee, 0xdc, 0xf9, 0xd7, 0xff, 0xfd, 0xc4, 0xee, 0x02, 0x17,
- 0x83, 0xf1, 0x76, 0x33, 0xfa, 0x3a, 0xce, 0x75, 0xfb, 0x8f, 0x38, 0x0f,
- 0x23, 0xf2, 0xf5, 0x8e, 0xba, 0x8d, 0xbf, 0xc2, 0x6a, 0xff, 0x9f, 0x76,
- 0xcf, 0x3c, 0xb1, 0x67, 0x5f, 0xff, 0xa4, 0xa4, 0x6b, 0x3a, 0xd4, 0xe4,
- 0x0e, 0xed, 0x3a, 0xff, 0xd2, 0x7f, 0xeb, 0x3e, 0x9b, 0xb0, 0x75, 0xa3,
- 0x11, 0x28, 0xa2, 0xad, 0x3a, 0x63, 0xfc, 0x28, 0x18, 0x67, 0xde, 0xfc,
- 0x7a, 0x75, 0xff, 0xfa, 0x21, 0xb1, 0xcf, 0x19, 0xb0, 0x7e, 0x18, 0xf2,
- 0x68, 0xbe, 0xef, 0xfd, 0xa4, 0x1d, 0xdb, 0xd0, 0xbe, 0x8e, 0xa6, 0x51,
- 0x47, 0xf6, 0x5b, 0xfc, 0xfb, 0x73, 0x19, 0x75, 0x73, 0xad, 0x23, 0xaf,
- 0xff, 0xf7, 0xa9, 0xd5, 0x38, 0xeb, 0x65, 0xa8, 0x3c, 0x7e, 0xb9, 0xd6,
- 0xfe, 0x1f, 0x8e, 0x84, 0x2f, 0xbe, 0x38, 0xd3, 0xa9, 0xcf, 0x1d, 0x09,
- 0xef, 0xfc, 0x28, 0xdf, 0xf3, 0x3a, 0x9a, 0x3a, 0xff, 0x71, 0xda, 0x39,
- 0x9b, 0x1d, 0x7f, 0xbf, 0xef, 0x91, 0x6f, 0x30, 0xf1, 0x00, 0xde, 0x8e,
- 0xb4, 0xf1, 0x00, 0xd6, 0x1f, 0x50, 0x50, 0xae, 0x86, 0x9e, 0x20, 0x1b,
- 0xe8, 0x1d, 0xda, 0x78, 0x80, 0x6f, 0xf2, 0x4b, 0x99, 0xef, 0xae, 0x78,
- 0x80, 0x6f, 0x20, 0x80, 0xf1, 0x00, 0xd0, 0x11, 0x6e, 0xb2, 0x2e, 0x17,
- 0x4e, 0x40, 0xbd, 0xd7, 0xf9, 0xe2, 0x01, 0xa3, 0xc4, 0x03, 0x73, 0xac,
- 0xf1, 0x00, 0xd0, 0x0d, 0xca, 0x0b, 0xdf, 0x22, 0xc0, 0xe7, 0x88, 0x06,
- 0xf7, 0xe2, 0x47, 0x88, 0x06, 0xff, 0xc3, 0x0d, 0x9b, 0x89, 0x28, 0xe9,
- 0xe2, 0x01, 0xbf, 0xfa, 0x3e, 0x1d, 0x90, 0x7f, 0xc8, 0x69, 0xe2, 0x01,
- 0xba, 0x00, 0x78, 0x80, 0x6f, 0xf0, 0xc3, 0x1a, 0xd3, 0xfa, 0x78, 0x80,
- 0x6f, 0xc8, 0xa4, 0x0f, 0xa7, 0x88, 0x06, 0xe4, 0xd1, 0xe2, 0x01, 0xae,
- 0x9e, 0xb7, 0xcd, 0x2f, 0xff, 0x71, 0x3f, 0xfc, 0xd7, 0x8e, 0xa3, 0xac,
- 0xf1, 0x00, 0xdf, 0xbe, 0x2f, 0xbb, 0x4d, 0x10, 0x0d, 0xde, 0xb9, 0xe2,
- 0x01, 0x98, 0xda, 0x5f, 0x91, 0xd7, 0x00, 0x3c, 0x40, 0x37, 0xc1, 0x81,
- 0x91, 0xe2, 0x01, 0xbc, 0xfd, 0x91, 0xe2, 0x01, 0xbf, 0xf6, 0x6f, 0xa0,
- 0x3e, 0x0f, 0xba, 0x3c, 0x40, 0x37, 0xe0, 0xc3, 0x5a, 0xe7, 0x88, 0x06,
- 0xfd, 0x12, 0xe3, 0xee, 0x78, 0x80, 0x6b, 0x11, 0x65, 0xc4, 0xb0, 0x99,
- 0xdd, 0xdf, 0x4f, 0x10, 0x0d, 0x35, 0x59, 0x28, 0x08, 0xb2, 0x12, 0xd2,
- 0x22, 0x48, 0x45, 0xf0, 0xd3, 0xd3, 0x2d, 0x16, 0xfe, 0x1b, 0x41, 0x2f,
- 0xbf, 0x67, 0xf5, 0x1b, 0x9e, 0x20, 0x1b, 0xfc, 0x07, 0x93, 0x3d, 0x7f,
- 0x9e, 0x20, 0x10, 0x1b, 0x4b, 0xdd, 0x76, 0x0f, 0x10, 0x0d, 0x48, 0xfe,
- 0x7a, 0xa1, 0x7f, 0x83, 0x0d, 0x6b, 0xf9, 0x59, 0xe2, 0x01, 0xbe, 0x41,
- 0x6e, 0x8f, 0x10, 0x0d, 0xfd, 0x0c, 0xb7, 0x37, 0x69, 0xe2, 0x01, 0xac,
- 0x46, 0x5f, 0x08, 0xbd, 0x41, 0x09, 0x6d, 0xff, 0x71, 0xf5, 0x36, 0x83,
- 0xdf, 0x4f, 0x10, 0x0d, 0x90, 0xf1, 0x00, 0xdd, 0x1b, 0x00, 0xf9, 0x38,
- 0x91, 0x77, 0x7d, 0x3c, 0x40, 0x37, 0xe8, 0xfe, 0x93, 0x73, 0xc4, 0x03,
- 0x7f, 0x20, 0x85, 0xb9, 0xa3, 0xc4, 0x03, 0x4e, 0x89, 0x01, 0x24, 0xf9,
- 0xa5, 0x01, 0x92, 0x99, 0x90, 0xd8, 0x64, 0xff, 0xac, 0x3c, 0x20, 0x82,
- 0xdf, 0x4a, 0x05, 0x2b, 0x52, 0xdd, 0x7f, 0x28, 0x4e, 0x7a, 0x14, 0x3e,
- 0x61, 0x7d, 0x7a, 0x22, 0x46, 0x88, 0x06, 0x64, 0x65, 0x5f, 0x28, 0xad,
- 0x80, 0xb3, 0xaf, 0xe4, 0x9c, 0x2e, 0x0e, 0x1d, 0x7f, 0xf3, 0x47, 0x25,
- 0xc4, 0xf7, 0xd0, 0xb2, 0x75, 0xde, 0xb9, 0x56, 0x50, 0xab, 0xdc, 0x7d,
- 0x8e, 0xb9, 0x86, 0x0a, 0xa4, 0x3d, 0xb5, 0x71, 0x66, 0x44, 0x58, 0x1c,
- 0xbc, 0xb4, 0xd1, 0x53, 0x1e, 0x05, 0xe4, 0x0f, 0xce, 0xbf, 0xfd, 0xfd,
- 0x62, 0x89, 0xdf, 0x3e, 0xfa, 0xfb, 0x9d, 0x5b, 0x33, 0x45, 0x5a, 0x40,
- 0x03, 0xc9, 0x52, 0xac, 0x50, 0xeb, 0xa5, 0x30, 0x5b, 0xec, 0x38, 0x7e,
- 0x5b, 0xe4, 0x6e, 0xff, 0xf0, 0xfe, 0x7b, 0x19, 0x6c, 0x77, 0x60, 0x39,
- 0xd7, 0xf7, 0xfc, 0xce, 0x9c, 0xfa, 0x3a, 0xff, 0x66, 0xff, 0xfc, 0x37,
- 0x47, 0x5e, 0x1d, 0xda, 0x78, 0xc0, 0x2b, 0x11, 0xb8, 0x89, 0xbd, 0x33,
- 0x83, 0x3b, 0xf3, 0x2d, 0x7e, 0xec, 0x75, 0xf3, 0xa8, 0xeb, 0x3a, 0xba,
- 0x79, 0x4b, 0x29, 0xbf, 0xf3, 0x75, 0xe0, 0x71, 0x6f, 0xd5, 0x0e, 0xbf,
- 0x9a, 0xfd, 0xf7, 0xca, 0xce, 0xbf, 0xfa, 0x70, 0xe6, 0xbf, 0x82, 0xdc,
- 0xd1, 0xd7, 0xcb, 0x70, 0xfc, 0xea, 0xc3, 0xe4, 0x84, 0x3b, 0xb9, 0x18,
- 0x8b, 0x41, 0x84, 0xa5, 0xff, 0x3c, 0x9d, 0x68, 0xbf, 0x50, 0xea, 0xe9,
- 0xf4, 0x2a, 0x31, 0xbf, 0xbc, 0xb1, 0xd4, 0xce, 0x15, 0x7f, 0xf7, 0xa2,
- 0x99, 0xbf, 0xd9, 0x6c, 0x74, 0xeb, 0xe6, 0x79, 0x0c, 0x9d, 0x7e, 0xc6,
- 0x5a, 0xfb, 0x9d, 0x7b, 0x88, 0xc9, 0xd7, 0x85, 0xda, 0x55, 0xff, 0x87,
- 0xd4, 0x54, 0xa8, 0x2d, 0x75, 0x73, 0xab, 0x0f, 0x7e, 0x06, 0xab, 0x74,
- 0xca, 0xfa, 0x8a, 0x24, 0x7f, 0x28, 0x54, 0xf7, 0x4e, 0xad, 0x27, 0x08,
- 0x92, 0x35, 0xce, 0x12, 0x44, 0x6b, 0x57, 0xf6, 0xfa, 0xef, 0x5f, 0xe7,
- 0x5f, 0xcd, 0xd2, 0x9d, 0x89, 0x1d, 0x78, 0x7f, 0xa3, 0xaf, 0xda, 0x08,
- 0x86, 0x47, 0x53, 0x9f, 0x82, 0x17, 0x04, 0x6e, 0xff, 0xee, 0x30, 0xfd,
- 0xd6, 0x31, 0x1d, 0x50, 0xeb, 0xa7, 0xed, 0x1d, 0x7e, 0x71, 0x4d, 0xda,
- 0x75, 0xff, 0x71, 0xfa, 0xf2, 0x41, 0x91, 0xd7, 0xdf, 0x52, 0x35, 0xd3,
- 0xdc, 0x54, 0x4d, 0x4d, 0x47, 0xc8, 0x51, 0x98, 0x77, 0xbf, 0xf7, 0x31,
- 0x54, 0x0a, 0x99, 0xbf, 0xce, 0xbf, 0xec, 0x97, 0x10, 0x1c, 0x0a, 0x87,
- 0x5e, 0xfe, 0x48, 0xea, 0x59, 0xea, 0x68, 0xe6, 0x94, 0x45, 0xb7, 0xb0,
- 0x94, 0xbf, 0xe5, 0x23, 0xc3, 0xac, 0x51, 0x43, 0xaf, 0xfd, 0x1a, 0x5b,
- 0xa7, 0x7a, 0x8c, 0x1d, 0x6d, 0x28, 0x7e, 0xfc, 0x3a, 0xbf, 0xec, 0xff,
- 0xd1, 0x4f, 0xe4, 0x8e, 0xbf, 0xc0, 0x7d, 0xf5, 0x9b, 0xfc, 0xeb, 0xfe,
- 0x7f, 0xa4, 0x90, 0x0f, 0xf3, 0xad, 0xa0, 0x22, 0x8b, 0x0e, 0x3a, 0x69,
- 0x5b, 0xa6, 0x01, 0xf8, 0x65, 0xdf, 0xf7, 0xd3, 0x67, 0xdf, 0xde, 0xb9,
- 0xd7, 0xb5, 0xfc, 0x3a, 0xec, 0xd7, 0x83, 0xd5, 0xf2, 0x75, 0x7f, 0x4f,
- 0x67, 0xfd, 0x8f, 0x9d, 0x7f, 0xfe, 0x7e, 0x46, 0x0b, 0xf5, 0x40, 0x06,
- 0x3a, 0xd3, 0xa9, 0xa8, 0xb4, 0xf9, 0x8a, 0xa3, 0x0a, 0x75, 0x7d, 0xa9,
- 0x0e, 0x78, 0x8e, 0x84, 0x31, 0x99, 0xdf, 0x71, 0x21, 0xa7, 0x5f, 0xf7,
- 0x70, 0x7c, 0x73, 0x37, 0x60, 0xeb, 0xfe, 0x68, 0x87, 0xdf, 0x12, 0x5f,
- 0xa7, 0x56, 0xc8, 0x98, 0xc2, 0x0d, 0xce, 0xef, 0xf8, 0x5f, 0x37, 0xfe,
- 0x75, 0xce, 0xa7, 0x3e, 0x78, 0x31, 0xbf, 0x44, 0xe0, 0x01, 0xce, 0xbb,
- 0x5a, 0x3a, 0xf3, 0x0c, 0x30, 0x75, 0xde, 0xc1, 0x53, 0x17, 0xf5, 0xd3,
- 0xdb, 0xd1, 0xad, 0xff, 0xb3, 0x43, 0x0a, 0x32, 0x28, 0xc9, 0xd7, 0xf7,
- 0xae, 0xde, 0x79, 0xd1, 0xd7, 0xa3, 0xdc, 0x2a, 0x9a, 0x99, 0x72, 0xe1,
- 0x07, 0xc2, 0x2f, 0x4f, 0xa7, 0x8c, 0x2f, 0xc0, 0xea, 0x07, 0x63, 0xaf,
- 0xf3, 0x18, 0x39, 0x39, 0x3a, 0x75, 0xfc, 0x39, 0xbf, 0xbe, 0x5a, 0x75,
- 0x32, 0x88, 0xb1, 0x28, 0xf9, 0x9d, 0xd0, 0xb3, 0xaf, 0xf6, 0x4e, 0xc9,
- 0x98, 0x61, 0x82, 0xaf, 0xcc, 0xbe, 0x73, 0x47, 0x50, 0x9e, 0xff, 0x93,
- 0x8b, 0xfd, 0x3f, 0x38, 0x65, 0xc4, 0xe9, 0xd7, 0x97, 0x1f, 0x3a, 0x99,
- 0x47, 0x4f, 0x1d, 0x02, 0x47, 0x38, 0xde, 0xfe, 0x19, 0xd0, 0xb4, 0x59,
- 0xd7, 0xec, 0x65, 0xae, 0xd3, 0xaf, 0xed, 0x80, 0xf8, 0x20, 0x3a, 0x9d,
- 0x55, 0xc2, 0x43, 0x7e, 0x23, 0x19, 0xd2, 0x07, 0xcb, 0x7c, 0x93, 0xde,
- 0x8f, 0x50, 0xeb, 0xcf, 0xd1, 0x3a, 0xff, 0x60, 0x06, 0x34, 0x80, 0x3a,
- 0xdc, 0x3a, 0xf0, 0x63, 0x61, 0x3c, 0x0d, 0x18, 0x59, 0x3a, 0x88, 0xdf,
- 0xad, 0x52, 0xd1, 0xa1, 0x3f, 0x42, 0xa2, 0xff, 0xf6, 0x02, 0x17, 0x9b,
- 0xb7, 0x3d, 0xc0, 0x1d, 0x77, 0x20, 0xeb, 0x99, 0xd1, 0xd7, 0xec, 0x9c,
- 0x82, 0x0c, 0x35, 0x9e, 0x45, 0x6f, 0xdc, 0xcd, 0xfe, 0xe7, 0x5f, 0x95,
- 0x46, 0xde, 0x5a, 0x75, 0x78, 0x4c, 0x1e, 0x67, 0x5c, 0x3f, 0x09, 0x3d,
- 0xf0, 0x33, 0x90, 0x75, 0xff, 0xcf, 0x82, 0xde, 0x60, 0x8b, 0xb0, 0x75,
- 0x93, 0xa8, 0xa0, 0x14, 0x0f, 0x90, 0x5f, 0xf6, 0x03, 0x05, 0xc4, 0x2e,
- 0x75, 0x6c, 0xeb, 0x1e, 0x5b, 0x2d, 0x08, 0x12, 0xcb, 0x70, 0xdd, 0x48,
- 0x45, 0x4a, 0x51, 0x0e, 0xe6, 0x89, 0x0b, 0xf6, 0x49, 0x3b, 0x4e, 0x03,
- 0x5c, 0x6f, 0x7c, 0x97, 0x9b, 0x0a, 0x9e, 0xc2, 0x78, 0x67, 0x44, 0xf5,
- 0x1a, 0x67, 0xe7, 0x01, 0x83, 0x19, 0x9c, 0xe8, 0xf5, 0x3c, 0x9a, 0x5f,
- 0xf6, 0x74, 0x5f, 0xed, 0xce, 0x1d, 0x7f, 0x0f, 0xb8, 0x08, 0x69, 0xd7,
- 0xfa, 0x43, 0x8d, 0x6c, 0x68, 0xeb, 0xf4, 0x37, 0xc0, 0x10, 0xeb, 0xcd,
- 0x7f, 0x4e, 0xbf, 0x79, 0x65, 0xae, 0xae, 0x55, 0x3a, 0x60, 0x98, 0x6c,
- 0x85, 0x9c, 0x31, 0xf9, 0x47, 0x91, 0xcb, 0x48, 0xeb, 0xff, 0x94, 0x10,
- 0xc7, 0x9c, 0xd2, 0x38, 0x9d, 0x7a, 0x79, 0x00, 0x75, 0x74, 0xf8, 0x56,
- 0x87, 0x7f, 0xf6, 0xff, 0x0a, 0xf8, 0xe8, 0x30, 0x03, 0xad, 0xe4, 0xd1,
- 0x02, 0xdb, 0xe6, 0xa0, 0x52, 0xc9, 0xf3, 0x78, 0xc0, 0xfd, 0xff, 0x92,
- 0x7b, 0x89, 0xe6, 0x6f, 0x7d, 0x72, 0xaf, 0xf8, 0x7f, 0xa0, 0xef, 0xf4,
- 0x60, 0xeb, 0xfc, 0x18, 0xd6, 0x60, 0xa8, 0x75, 0x39, 0xf5, 0xf0, 0xea,
- 0xff, 0xf2, 0x29, 0xe0, 0x61, 0x4f, 0x1a, 0xf7, 0xd7, 0x3a, 0xff, 0x47,
- 0x37, 0xd3, 0x8f, 0xce, 0xad, 0x22, 0x0b, 0xea, 0x17, 0xcd, 0xe6, 0x6c,
- 0x75, 0xff, 0x3e, 0xeb, 0x8f, 0xe6, 0xff, 0x3a, 0xb7, 0x3d, 0xb1, 0x22,
- 0xbf, 0xe7, 0x97, 0xc3, 0xce, 0xbb, 0x07, 0x5f, 0xff, 0xee, 0x3f, 0x7d,
- 0xc9, 0xc9, 0xad, 0x60, 0xca, 0x07, 0xd3, 0xaf, 0xcf, 0x83, 0xf9, 0xe3,
- 0xac, 0xb3, 0xa9, 0x66, 0xe0, 0x4a, 0x2f, 0x34, 0x20, 0x3a, 0xf6, 0xa3,
- 0x7f, 0x06, 0xf2, 0x08, 0x2f, 0xff, 0xec, 0x1d, 0xb5, 0xa7, 0xf7, 0x38,
- 0x9d, 0x86, 0x3e, 0x75, 0x01, 0x57, 0x06, 0xf0, 0xa3, 0xeb, 0xf2, 0xc8,
- 0xb8, 0x73, 0xf8, 0x6a, 0xb0, 0x69, 0x4e, 0xb8, 0x04, 0x92, 0xe4, 0x2f,
- 0xff, 0xfb, 0xbb, 0x62, 0x33, 0x10, 0xdd, 0x3a, 0xc1, 0xc7, 0x19, 0x1d,
- 0x7c, 0x0e, 0x07, 0x63, 0xaf, 0xf0, 0x21, 0xb9, 0xb0, 0x44, 0xeb, 0x6c,
- 0xe7, 0xab, 0x84, 0x77, 0x4f, 0xd8, 0x75, 0x61, 0xe0, 0xc1, 0x3d, 0xfd,
- 0xf9, 0xe0, 0xf3, 0x24, 0x75, 0xfe, 0xeb, 0xfd, 0x3d, 0x76, 0x9d, 0x7b,
- 0x61, 0x69, 0xd5, 0x3e, 0xaf, 0x7f, 0xbb, 0x8a, 0x11, 0x2d, 0xff, 0x93,
- 0x85, 0x30, 0x56, 0x30, 0xfb, 0xd1, 0x07, 0xcc, 0x02, 0x65, 0x7f, 0x9a,
- 0xce, 0x0c, 0x73, 0x0e, 0xbf, 0xd3, 0xa1, 0x90, 0x38, 0xec, 0x75, 0xf3,
- 0x86, 0x7e, 0x43, 0xaf, 0xf2, 0x75, 0xf6, 0x8e, 0xc8, 0xeb, 0x7f, 0xa7,
- 0xaf, 0xf2, 0x5b, 0xff, 0xdd, 0x90, 0xe4, 0xe1, 0xc7, 0xeb, 0xe8, 0xeb,
- 0xfd, 0x0c, 0xf3, 0x17, 0x9a, 0x3a, 0xb0, 0xfe, 0xa7, 0x24, 0x5f, 0xc8,
- 0xa7, 0xf3, 0x16, 0x75, 0xfb, 0x00, 0x9d, 0xd1, 0xd7, 0xbf, 0xfd, 0xce,
- 0xbf, 0xfb, 0x79, 0x27, 0x3c, 0x2a, 0xce, 0x22, 0xce, 0xaf, 0x4f, 0x97,
- 0xe3, 0xb7, 0x07, 0xa7, 0x56, 0x8d, 0xcc, 0xf1, 0x1d, 0x9f, 0x64, 0x74,
- 0x31, 0x0c, 0x4a, 0x75, 0x52, 0x99, 0x08, 0xc4, 0x85, 0x17, 0x08, 0xff,
- 0x18, 0xa5, 0xff, 0x85, 0x3c, 0xef, 0x93, 0xb7, 0x7f, 0x27, 0x5f, 0xfe,
- 0x4c, 0xe8, 0x1d, 0x8c, 0xe3, 0xef, 0xa3, 0xaf, 0xbc, 0xbf, 0x7d, 0x3a,
- 0xe8, 0xe9, 0xd7, 0xf7, 0xd3, 0x65, 0xbc, 0x8e, 0xa0, 0x1e, 0x17, 0x05,
- 0x6e, 0xc5, 0x47, 0x5f, 0x7b, 0xe4, 0x5a, 0x75, 0xde, 0xc0, 0x9b, 0xbf,
- 0x8b, 0xd3, 0xa2, 0x24, 0x2b, 0xb7, 0x6e, 0xc9, 0xd7, 0xef, 0x3f, 0xf5,
- 0x78, 0x75, 0x2c, 0xf0, 0xbd, 0x18, 0xbd, 0x27, 0xd1, 0xd7, 0xff, 0x2f,
- 0x4b, 0x70, 0x3f, 0x42, 0xfe, 0x9d, 0x7f, 0xe7, 0x81, 0xcf, 0xfd, 0x18,
- 0xf9, 0xd4, 0xe8, 0xbe, 0xc2, 0x34, 0x1b, 0x0a, 0x25, 0x3a, 0xef, 0xb3,
- 0x65, 0x62, 0xe2, 0xcc, 0x91, 0x19, 0x49, 0xd4, 0x3b, 0xff, 0x19, 0x15,
- 0xfe, 0xea, 0x63, 0x19, 0xbf, 0xce, 0xbf, 0xfd, 0xac, 0x10, 0xcb, 0x98,
- 0xb6, 0x62, 0x47, 0x5f, 0xe1, 0x53, 0x8e, 0xb5, 0x89, 0xd7, 0xe7, 0x67,
- 0x32, 0x47, 0x56, 0x1e, 0xc7, 0x0c, 0xaf, 0xfe, 0x4e, 0x63, 0x28, 0xc8,
- 0x55, 0x07, 0x47, 0x5f, 0x9d, 0x57, 0x1d, 0x93, 0xa9, 0xa7, 0xe1, 0xa4,
- 0x7b, 0xff, 0x82, 0xca, 0x71, 0xf7, 0x6b, 0xb2, 0xe7, 0x5f, 0x81, 0x02,
- 0xfc, 0x3a, 0xff, 0xfb, 0x5f, 0xd2, 0x7a, 0xed, 0xd6, 0x66, 0xff, 0x3a,
- 0xc9, 0xc3, 0xf5, 0x60, 0x96, 0xff, 0xfd, 0xd0, 0xf7, 0xae, 0x38, 0xa2,
- 0x73, 0x99, 0xe4, 0xeb, 0xf8, 0x61, 0x00, 0xe2, 0x75, 0xf6, 0xce, 0xa9,
- 0xce, 0xbd, 0x38, 0x3c, 0x3a, 0xff, 0xe4, 0x5a, 0x6b, 0x8e, 0x9d, 0x0a,
- 0xb9, 0xd4, 0xe8, 0x86, 0x42, 0x38, 0x1e, 0xbf, 0xe7, 0xf3, 0xf4, 0xea,
- 0x7c, 0x27, 0x5f, 0xc1, 0xf3, 0xcc, 0xdf, 0x47, 0x5f, 0xff, 0xff, 0xba,
- 0xff, 0x18, 0x92, 0x69, 0x94, 0xec, 0x9f, 0x5f, 0x7d, 0xdf, 0xce, 0x68,
- 0xeb, 0xff, 0xff, 0xff, 0x6b, 0x59, 0xfe, 0x42, 0xf5, 0xde, 0xa6, 0xff,
- 0x88, 0x53, 0x31, 0x90, 0xfd, 0xd8, 0xdd, 0xce, 0xa7, 0x4c, 0x7e, 0x21,
- 0x07, 0x7d, 0xec, 0x6f, 0xa3, 0xae, 0x61, 0x83, 0xab, 0x46, 0xed, 0x82,
- 0x3b, 0xf2, 0x72, 0x33, 0x85, 0x4c, 0x68, 0xaf, 0xfc, 0x81, 0xfb, 0x8c,
- 0xa7, 0xcf, 0x56, 0x75, 0x3a, 0xf1, 0x03, 0x4c, 0xc1, 0x0a, 0x1d, 0xe1,
- 0x22, 0xae, 0x44, 0xcc, 0x2e, 0xba, 0x50, 0xb5, 0x6e, 0x42, 0xbf, 0xd2,
- 0xd9, 0xf8, 0xe4, 0x63, 0x4f, 0xd4, 0x21, 0x3e, 0x6d, 0x7e, 0x65, 0xd9,
- 0xe3, 0x9d, 0x79, 0x86, 0x18, 0x2a, 0xf9, 0xbf, 0xc9, 0x15, 0x31, 0x7f,
- 0x7e, 0xc0, 0x27, 0xba, 0x3d, 0xdf, 0xd5, 0xd3, 0xe5, 0x13, 0x1a, 0x74,
- 0x66, 0xc4, 0x2b, 0x2d, 0xa3, 0xaf, 0xf7, 0xf7, 0x6f, 0x1c, 0x76, 0x3a,
- 0xfd, 0xb2, 0xc3, 0xbf, 0xce, 0xae, 0x9f, 0x70, 0x88, 0x7c, 0xd2, 0xff,
- 0x85, 0xd8, 0xd2, 0x0e, 0xed, 0x3a, 0xe7, 0x91, 0xd4, 0x27, 0x9b, 0x38,
- 0xe2, 0x9d, 0x13, 0xc8, 0xf7, 0x7f, 0x0e, 0xfa, 0x67, 0x3e, 0x75, 0xff,
- 0xef, 0xb3, 0x9d, 0xc8, 0x5b, 0xf1, 0x00, 0x75, 0xfc, 0x15, 0xe7, 0x37,
- 0x83, 0xa8, 0x4f, 0xd7, 0x49, 0x17, 0xff, 0x90, 0x03, 0x1b, 0x8e, 0x7f,
- 0x13, 0xd3, 0xaf, 0xe7, 0xff, 0x1b, 0xa0, 0x9d, 0x7f, 0xce, 0x3d, 0x74,
- 0x6c, 0x68, 0xeb, 0xf6, 0xca, 0xe9, 0x9b, 0x9d, 0x7e, 0x4d, 0x3e, 0xcb,
- 0x3d, 0x9f, 0xb7, 0xe7, 0x8e, 0xfa, 0x13, 0xd9, 0xfb, 0x74, 0x34, 0xf6,
- 0x7e, 0xdf, 0x05, 0xb9, 0xa3, 0xd9, 0xfb, 0x40, 0x3d, 0x01, 0x22, 0xbf,
- 0x3e, 0x6b, 0x04, 0xf6, 0x7e, 0xd1, 0xec, 0xfd, 0xba, 0x3e, 0x7b, 0x3f,
- 0x56, 0x5b, 0xd9, 0xa2, 0x7f, 0x21, 0x48, 0xbe, 0xc9, 0xe4, 0xf4, 0xf6,
- 0x7e, 0xd1, 0xec, 0xfd, 0xbb, 0xd7, 0x3d, 0x9f, 0xb7, 0xfd, 0x9e, 0xc7,
- 0x72, 0x76, 0x00, 0xf6, 0x7e, 0xdf, 0xd9, 0xc4, 0xd0, 0x76, 0x3d, 0x9f,
- 0xb5, 0xea, 0x28, 0xc4, 0x8f, 0x48, 0xd7, 0xdd, 0xd9, 0xfe, 0x7b, 0x3f,
- 0x68, 0xf6, 0x7e, 0xe1, 0xaf, 0xb9, 0x86, 0x0f, 0x67, 0xed, 0x35, 0x58,
- 0x70, 0x0d, 0x32, 0x10, 0x9b, 0xc2, 0x6b, 0xa4, 0xeb, 0x31, 0xd4, 0x2e,
- 0xbe, 0xbe, 0xc1, 0x35, 0xf6, 0x35, 0xd4, 0x2d, 0x9f, 0xa9, 0x91, 0x21,
- 0x7f, 0xec, 0x90, 0x33, 0xac, 0x47, 0x19, 0x3a, 0xe6, 0xec, 0x55, 0xf3,
- 0x31, 0x1d, 0x3a, 0xb6, 0x45, 0xce, 0xe8, 0x42, 0x7e, 0xa8, 0x5e, 0xba,
- 0xb9, 0x85, 0x13, 0x90, 0x57, 0xff, 0xe6, 0xf5, 0xe7, 0x43, 0x2e, 0x0e,
- 0x3a, 0xe1, 0x93, 0xaf, 0xf2, 0xa8, 0xd2, 0x69, 0x9c, 0x3a, 0xb7, 0x44,
- 0x5f, 0x55, 0xe9, 0xd9, 0x0b, 0xcd, 0x8c, 0xcb, 0x08, 0x52, 0x14, 0x6a,
- 0xe4, 0x3d, 0x47, 0xe1, 0x6c, 0x4e, 0x7b, 0x86, 0x17, 0x17, 0xff, 0xfc,
- 0x9c, 0x8e, 0x3b, 0x66, 0xcf, 0x5d, 0xba, 0x07, 0x1f, 0xa7, 0x5f, 0xf9,
- 0x47, 0xdc, 0x5f, 0x9c, 0x0c, 0x8e, 0xbf, 0xfc, 0x0e, 0xbe, 0x0e, 0x35,
- 0x39, 0x93, 0x8e, 0xbf, 0x86, 0x14, 0xe4, 0x34, 0xeb, 0xcc, 0x30, 0xc1,
- 0x57, 0xbc, 0xbf, 0xa5, 0x4c, 0x5f, 0xdf, 0xf4, 0x37, 0xcf, 0x72, 0x74,
- 0x74, 0xeb, 0xff, 0xf7, 0x31, 0xbe, 0x44, 0x73, 0x66, 0x5a, 0xfd, 0xd8,
- 0xea, 0x14, 0x49, 0xfc, 0xee, 0xf9, 0xaf, 0xee, 0xe7, 0x5f, 0xde, 0xb8,
- 0xe6, 0xff, 0x3a, 0xf0, 0xc7, 0xbe, 0x0f, 0x43, 0xc9, 0x1d, 0xe9, 0xcf,
- 0xd3, 0xa9, 0xaa, 0xaf, 0xc0, 0xcd, 0x87, 0xeb, 0x48, 0xf5, 0x2c, 0x61,
- 0x83, 0xf7, 0x29, 0xc6, 0xf7, 0x80, 0x9b, 0x1d, 0x6f, 0x4e, 0xbf, 0xf2,
- 0x7f, 0x99, 0xaf, 0x1f, 0x4d, 0x8e, 0xbf, 0xe1, 0x40, 0xcf, 0xda, 0x9e,
- 0x7f, 0x9d, 0x4d, 0x44, 0x87, 0x04, 0x45, 0x02, 0xf3, 0x0c, 0x30, 0x58,
- 0x84, 0x17, 0xee, 0xca, 0x22, 0x45, 0x88, 0x41, 0x31, 0xad, 0xbc, 0xc3,
- 0x0c, 0x16, 0x20, 0xf5, 0x16, 0x20, 0xf4, 0xc6, 0xb6, 0xcb, 0xc4, 0x4d,
- 0xc9, 0xca, 0xff, 0xee, 0x3b, 0x53, 0xf9, 0xc9, 0x3a, 0xce, 0xa7, 0x3e,
- 0xa9, 0xc5, 0x17, 0xff, 0xb3, 0x89, 0xde, 0x46, 0x69, 0x23, 0x63, 0xaf,
- 0x9f, 0xee, 0xb3, 0xa9, 0x67, 0xcf, 0xf4, 0x7b, 0xf9, 0x88, 0x00, 0x63,
- 0xc9, 0xd7, 0xc2, 0x8e, 0xa1, 0xd7, 0xbc, 0xbf, 0xa7, 0x56, 0xc6, 0xf9,
- 0x64, 0x17, 0xe9, 0x3f, 0x1d, 0x65, 0x5f, 0x86, 0x04, 0x70, 0xab, 0xb2,
- 0x45, 0x5c, 0xc3, 0x05, 0x56, 0x1f, 0xb6, 0x89, 0xbe, 0x46, 0xc0, 0xad,
- 0xfe, 0x1f, 0x2f, 0xef, 0x31, 0x51, 0x53, 0x1b, 0xca, 0x74, 0xea, 0xb0,
- 0x89, 0x1b, 0x62, 0x1a, 0x97, 0xff, 0x3f, 0xba, 0xcc, 0x04, 0x0c, 0x28,
- 0x75, 0xff, 0xf3, 0x74, 0xc3, 0xf7, 0x8e, 0x9c, 0x71, 0x43, 0xaf, 0xff,
- 0xb4, 0x39, 0xbf, 0xb1, 0xa8, 0xea, 0x6f, 0xe9, 0xd5, 0xba, 0x27, 0x98,
- 0x4d, 0xae, 0x26, 0x0b, 0x10, 0xe0, 0xbf, 0x92, 0x40, 0xc8, 0xf4, 0xeb,
- 0xff, 0xff, 0x3e, 0xd3, 0x6b, 0xfa, 0xdf, 0xc0, 0x30, 0x0f, 0x1d, 0xc1,
- 0xf4, 0xeb, 0xf2, 0xf4, 0xc4, 0x6e, 0x75, 0xb4, 0x04, 0x4c, 0xf9, 0x70,
- 0xbf, 0xb1, 0x96, 0xa7, 0x74, 0x75, 0x3a, 0xfa, 0x18, 0x1e, 0x72, 0x15,
- 0x89, 0x1b, 0x0f, 0x65, 0x1a, 0x44, 0x68, 0x82, 0x51, 0xa8, 0x62, 0xfc,
- 0xae, 0xf3, 0x0c, 0x30, 0x55, 0xf7, 0xb0, 0x20, 0x2a, 0x62, 0xfe, 0xfb,
- 0x89, 0x0d, 0x3a, 0xff, 0x87, 0xfa, 0x4e, 0xf5, 0x16, 0x75, 0xef, 0x0a,
- 0x4f, 0x1d, 0x7b, 0xf0, 0x03, 0xab, 0xa6, 0xf7, 0x44, 0x57, 0xf7, 0x9c,
- 0xee, 0x63, 0x27, 0x53, 0x53, 0x14, 0x01, 0x8e, 0x10, 0x23, 0xa6, 0x88,
- 0x6f, 0xff, 0x87, 0x7f, 0x1b, 0xfa, 0xe3, 0x28, 0xd8, 0x60, 0xeb, 0xff,
- 0xff, 0xfe, 0xfe, 0xbc, 0xeb, 0xc7, 0x21, 0x3e, 0x9c, 0x92, 0x78, 0x6a,
- 0x72, 0x07, 0xed, 0xce, 0xe1, 0xd7, 0xff, 0x4c, 0x01, 0x70, 0xcb, 0x14,
- 0x4e, 0x9d, 0x76, 0x30, 0x75, 0xb1, 0xcf, 0x6b, 0x48, 0x97, 0xca, 0xb9,
- 0xec, 0xe3, 0xa9, 0xa7, 0x9b, 0x04, 0xd7, 0xff, 0x67, 0x7d, 0x5a, 0x6b,
- 0xce, 0x9f, 0x0e, 0xbd, 0x0a, 0xfa, 0x3a, 0x9a, 0x7c, 0x70, 0x8b, 0x78,
- 0x18, 0xb3, 0xaf, 0xbd, 0xfe, 0x7a, 0x75, 0x21, 0xbe, 0xe8, 0xdd, 0xff,
- 0x4b, 0x82, 0xfb, 0xa3, 0xf0, 0xea, 0x75, 0x62, 0x6d, 0x49, 0xc5, 0x28,
- 0x8c, 0xf8, 0x61, 0x08, 0x15, 0xff, 0x24, 0x17, 0xfe, 0x84, 0x00, 0x7f,
- 0xad, 0xb1, 0x83, 0xaf, 0xda, 0xc5, 0x1f, 0x47, 0x5f, 0xca, 0xfa, 0x41,
- 0xdd, 0xa7, 0x5f, 0xfa, 0x3b, 0x3c, 0x9c, 0xc8, 0xdf, 0xd3, 0xaf, 0xff,
- 0xc9, 0xf7, 0x5e, 0x6f, 0xf7, 0x5f, 0x9e, 0xc7, 0xa7, 0x5f, 0x20, 0xc0,
- 0x0e, 0xbf, 0xed, 0x3f, 0x7e, 0xf3, 0x01, 0x0e, 0xa6, 0xa2, 0xb8, 0x0a,
- 0xfa, 0x1f, 0xbf, 0xfd, 0xa4, 0xeb, 0xb7, 0x8e, 0xc8, 0x85, 0x43, 0xae,
- 0x94, 0xf1, 0xd7, 0xf2, 0x9f, 0x7e, 0x3e, 0x8e, 0xbf, 0xb8, 0x9b, 0xea,
- 0x37, 0x3a, 0x9a, 0x7e, 0x88, 0x33, 0xe9, 0x6d, 0xff, 0x86, 0x19, 0xe4,
- 0x77, 0xa8, 0x03, 0xaf, 0xbc, 0x01, 0x04, 0xea, 0x6a, 0xac, 0x2c, 0x27,
- 0x91, 0x82, 0x43, 0xbd, 0x93, 0x0e, 0xc2, 0xf9, 0x65, 0xec, 0x1e, 0xdd,
- 0xef, 0xce, 0xbe, 0xef, 0x73, 0x47, 0x5d, 0x8c, 0x9d, 0x66, 0xec, 0x79,
- 0xd0, 0x2f, 0xe4, 0x86, 0xfd, 0xd0, 0x66, 0x09, 0xd7, 0xff, 0x2b, 0xa6,
- 0x71, 0xe7, 0x6b, 0x8f, 0xb9, 0xd5, 0x07, 0xdb, 0xa2, 0x5b, 0xfe, 0xc1,
- 0xee, 0x6b, 0x13, 0x87, 0x5f, 0xff, 0x37, 0xe3, 0x91, 0xf1, 0xcf, 0xff,
- 0x18, 0x3a, 0xff, 0xf7, 0xf5, 0x8c, 0xf1, 0xe7, 0x67, 0x38, 0xe7, 0x5f,
- 0xdc, 0x02, 0x4e, 0x70, 0x1d, 0x58, 0x7f, 0x30, 0x97, 0x7d, 0x9f, 0x4d,
- 0x1d, 0x7f, 0x2b, 0x2c, 0x8c, 0xf9, 0xb0, 0x4e, 0xad, 0x1e, 0xcf, 0xc8,
- 0x28, 0x09, 0xdb, 0xc8, 0x87, 0x73, 0x51, 0x86, 0x37, 0xde, 0x6f, 0xff,
- 0x93, 0x58, 0x0f, 0xe9, 0x14, 0xe4, 0x0a, 0x1d, 0x7f, 0xe8, 0x57, 0xf4,
- 0x3a, 0x41, 0xdd, 0xa7, 0x5f, 0xff, 0xdf, 0xce, 0x23, 0xfd, 0x3d, 0x76,
- 0xcc, 0xc3, 0x0c, 0x15, 0x7f, 0xb8, 0x18, 0x58, 0x21, 0x67, 0x50, 0xa2,
- 0x43, 0xeb, 0xd7, 0xc0, 0xcc, 0x50, 0xab, 0xe8, 0xf6, 0x3e, 0x75, 0xff,
- 0x76, 0x25, 0xe3, 0x8f, 0xe4, 0x4e, 0xbc, 0x17, 0xe9, 0xd7, 0x7f, 0x40,
- 0x3d, 0x66, 0x4e, 0xef, 0x34, 0x42, 0x68, 0x86, 0x6f, 0x30, 0xc3, 0x05,
- 0x5e, 0xc1, 0x91, 0x53, 0x17, 0xf7, 0xfe, 0xcd, 0xb0, 0x10, 0xd1, 0x7d,
- 0x8e, 0xaf, 0x4f, 0x9c, 0x4a, 0xaf, 0xa0, 0x55, 0xba, 0x7f, 0x3a, 0xff,
- 0x34, 0x73, 0xff, 0x0e, 0xc7, 0x5e, 0x85, 0x77, 0x3a, 0xfd, 0x80, 0xe4,
- 0x2b, 0x9d, 0x4e, 0xa9, 0x7b, 0x62, 0x20, 0x10, 0xe3, 0xbe, 0xe5, 0xfd,
- 0x85, 0x77, 0x08, 0xa0, 0xb0, 0x26, 0x73, 0x87, 0x6f, 0xf3, 0xaf, 0x13,
- 0xac, 0xb4, 0xeb, 0xe4, 0xfa, 0x39, 0xd7, 0xff, 0xee, 0x47, 0x75, 0x88,
- 0x31, 0xfd, 0x30, 0xe2, 0x75, 0xf8, 0x09, 0xd7, 0xf9, 0xd7, 0xff, 0x69,
- 0xd4, 0xd2, 0xdf, 0x5e, 0xa4, 0x8e, 0xbf, 0xc1, 0xce, 0xfb, 0xea, 0x09,
- 0xd7, 0xfe, 0xc5, 0xa0, 0x3b, 0x80, 0x85, 0x9d, 0x7d, 0x8b, 0xf2, 0x03,
- 0xab, 0x87, 0xbe, 0x27, 0x97, 0xff, 0x90, 0x1c, 0xf3, 0xac, 0xec, 0xa2,
- 0x24, 0x68, 0x83, 0x2f, 0x83, 0xcc, 0x91, 0xd4, 0xd3, 0xf8, 0x9e, 0x57,
- 0xbd, 0xc0, 0xab, 0x9d, 0x7f, 0xfb, 0xb1, 0x3b, 0x06, 0x5c, 0x4f, 0x7c,
- 0xfc, 0xea, 0x74, 0x48, 0xcf, 0xc4, 0xa1, 0x1f, 0xad, 0xd5, 0x1a, 0xf1,
- 0x17, 0x50, 0x92, 0xfc, 0x65, 0x57, 0xfc, 0xb4, 0x63, 0x04, 0x1c, 0x73,
- 0xae, 0xe0, 0x4e, 0xbf, 0xff, 0x35, 0x04, 0x1c, 0xcd, 0xfc, 0xc0, 0xfc,
- 0x40, 0x75, 0xe4, 0x61, 0x5c, 0xeb, 0xfd, 0x93, 0xb5, 0xff, 0xba, 0xce,
- 0xae, 0x9e, 0x9f, 0x07, 0xeb, 0x13, 0x17, 0x43, 0x76, 0x45, 0xb5, 0x0a,
- 0x8b, 0xfd, 0x3d, 0x9a, 0x9e, 0xce, 0xb9, 0xd7, 0xff, 0xc2, 0xf2, 0xf1,
- 0xdc, 0x40, 0xcf, 0xd8, 0xab, 0x0e, 0xa6, 0xae, 0x7e, 0x00, 0x7f, 0x14,
- 0x92, 0x52, 0xde, 0xa3, 0x62, 0xfa, 0x12, 0xa3, 0x7b, 0xfa, 0x76, 0x0a,
- 0x2a, 0x73, 0xaf, 0xf8, 0x3f, 0xf4, 0x2b, 0x7c, 0xf9, 0xd7, 0xff, 0x87,
- 0x6f, 0x0c, 0xa0, 0xe0, 0x30, 0x54, 0x3a, 0xf7, 0x9c, 0x73, 0xa9, 0xcf,
- 0x9e, 0x12, 0xef, 0x3f, 0x59, 0x3a, 0xbc, 0x36, 0x26, 0x6f, 0x2c, 0x04,
- 0x10, 0xcb, 0xc9, 0x4b, 0x72, 0x50, 0xdd, 0x35, 0x25, 0x98, 0x72, 0x12,
- 0x71, 0x3a, 0x5d, 0xeb, 0xa0, 0x97, 0x06, 0x14, 0x13, 0xc4, 0x17, 0xb7,
- 0xda, 0x71, 0xd7, 0xfb, 0x7f, 0x12, 0xe3, 0xee, 0xa8, 0xeb, 0xf4, 0x2e,
- 0x33, 0x47, 0x5f, 0xff, 0x49, 0xf5, 0xa7, 0x5e, 0x7d, 0x35, 0xc8, 0x3a,
- 0xff, 0x08, 0xbb, 0x56, 0xe8, 0x75, 0xfe, 0xfa, 0x4e, 0x4f, 0xb5, 0xca,
- 0xb2, 0xce, 0xbf, 0xb0, 0x54, 0xeb, 0xcc, 0x87, 0x87, 0xe4, 0xce, 0xb1,
- 0x30, 0x54, 0x4d, 0xd3, 0x95, 0xf7, 0x43, 0xbb, 0x4e, 0xbf, 0xc2, 0xd1,
- 0xc5, 0xbc, 0x8e, 0xbc, 0xb0, 0x61, 0xd4, 0xe7, 0xdd, 0x84, 0x70, 0x61,
- 0x7a, 0x78, 0x3f, 0x3a, 0xff, 0xf7, 0xdd, 0x68, 0x0c, 0x15, 0x38, 0xeb,
- 0x3a, 0xa4, 0x7c, 0xff, 0x1f, 0xbf, 0x7f, 0xfa, 0x8f, 0x4e, 0xbf, 0x3a,
- 0xff, 0x92, 0x3a, 0xe4, 0xd8, 0xea, 0x43, 0xe4, 0xe1, 0x47, 0xc9, 0xaf,
- 0xcc, 0x20, 0x15, 0x21, 0xd7, 0xfd, 0x9f, 0xe6, 0x2c, 0x63, 0xe7, 0x5f,
- 0xd3, 0x93, 0xbb, 0xba, 0xb9, 0xd6, 0x10, 0x1f, 0x46, 0x1b, 0x5f, 0x96,
- 0xf2, 0xd8, 0x07, 0x5f, 0xbb, 0xea, 0xd3, 0x47, 0x5d, 0xfd, 0x61, 0xe8,
- 0x79, 0x28, 0xa7, 0x45, 0x28, 0x5d, 0xad, 0xa3, 0xaf, 0xe7, 0xdb, 0x05,
- 0x14, 0x3a, 0xba, 0x6f, 0x34, 0x21, 0x7f, 0xf3, 0x8c, 0x71, 0xfd, 0x9b,
- 0xba, 0xd1, 0x54, 0x04, 0x61, 0xe2, 0xf2, 0xc8, 0x6f, 0xf4, 0x03, 0x5a,
- 0x7e, 0xb4, 0xeb, 0x83, 0xb1, 0xd7, 0xfb, 0x76, 0xef, 0xa4, 0xfb, 0x9d,
- 0x79, 0x37, 0xd1, 0xd5, 0x87, 0xa0, 0x86, 0x94, 0x88, 0x87, 0xe3, 0x3d,
- 0xd9, 0x23, 0xaf, 0x77, 0x34, 0x77, 0xcb, 0x5b, 0xff, 0xe0, 0x78, 0x84,
- 0xcd, 0x3e, 0xd8, 0x28, 0xa1, 0xd7, 0xfb, 0xab, 0x7d, 0xff, 0x12, 0x3a,
- 0xb1, 0x10, 0x48, 0x9f, 0x7f, 0x3b, 0x28, 0xb7, 0x64, 0xeb, 0xb1, 0x83,
- 0xa8, 0xab, 0xfb, 0x5e, 0x5f, 0xae, 0xb2, 0xa8, 0xaa, 0x2a, 0x8a, 0xa2,
- 0xa9, 0xa7, 0xc0, 0x81, 0x5e, 0x97, 0x04, 0x2a, 0x78, 0x29, 0x50, 0x55,
- 0xdc, 0xc2, 0xaf, 0xe8, 0x8f, 0xb2, 0xeb, 0x2b, 0xc1, 0x6b, 0x69, 0xf8,
- 0xaa, 0x2a, 0x8a, 0xa6, 0x96, 0x88, 0x15, 0x45, 0x51, 0x54, 0x55, 0x15,
- 0x45, 0x51, 0x55, 0xb1, 0xbc, 0x00, 0x52, 0x05, 0x7a, 0x15, 0xa0, 0xa9,
- 0xc1, 0x54, 0x55, 0x15, 0x4d, 0x2d, 0x34, 0x15, 0x45, 0x51, 0x54, 0x55,
- 0x15, 0x4d, 0x35, 0x1e, 0x85, 0x7c, 0x29, 0x50, 0x55, 0x15, 0x45, 0x51,
- 0x54, 0x55, 0x6c, 0x6a, 0x14, 0x0a, 0xe8, 0x57, 0x02, 0xac, 0xa1, 0x54,
- 0x55, 0x15, 0x45, 0x51, 0x54, 0x03, 0x51, 0xb8, 0x57, 0xa1, 0x41, 0x0a,
- 0xa2, 0xa8, 0xaa, 0x2a, 0xfd, 0xc7, 0xf7, 0x58, 0x55, 0x15, 0x4d, 0x3c,
- 0xf9, 0x05, 0x70, 0x2a, 0x02, 0xbd, 0x27, 0xb4, 0x8a, 0xa2, 0xa8, 0xaa,
- 0x2a, 0x8a, 0xa6, 0x9a, 0x8d, 0xc2, 0x90, 0x2a, 0x70, 0x55, 0x15, 0x45,
- 0x51, 0x54, 0x55, 0x34, 0xd4, 0x00, 0x2b, 0x81, 0x42, 0x15, 0x6e, 0x15,
- 0x45, 0x51, 0x56, 0x69, 0x54, 0x56, 0xe5, 0x85, 0x15, 0x45, 0x51, 0x54,
- 0x55, 0x6c, 0x7c, 0xcd, 0x0a, 0x50, 0x6a, 0x43, 0x4c, 0x85, 0x7a, 0x15,
- 0xf0, 0xab, 0x61, 0x54, 0x55, 0x15, 0x66, 0x95, 0x45, 0x6e, 0x58, 0x51,
- 0x54, 0x55, 0x39, 0xe9, 0x34, 0x29, 0x06, 0xba, 0x34, 0xb0, 0xaa, 0x2a,
- 0x8a, 0xa2, 0xa8, 0xaa, 0x2a, 0x9c, 0xd9, 0x6e, 0x15, 0xd0, 0xa5, 0x85,
- 0x08, 0x55, 0x15, 0x45, 0x51, 0x55, 0xd2, 0xfb, 0x41, 0x5f, 0x0a, 0xa2,
- 0xa8, 0xaa, 0x2a, 0x96, 0x5f, 0x08, 0x57, 0xc2, 0xac, 0xb2, 0xa8, 0xaa,
- 0x2a, 0xbd, 0x2d, 0x02, 0x15, 0x45, 0x51, 0x54, 0x55, 0x15, 0x4e, 0x6a,
- 0x19, 0x0a, 0xe0, 0x50, 0x42, 0xa9, 0xd7, 0xea, 0x36, 0x70, 0x69, 0xe8,
- 0x0a, 0x71, 0x6e, 0x4d, 0x9b, 0xa4, 0x23, 0x32, 0xb9, 0xeb, 0x27, 0x3d,
- 0x84, 0x62, 0xd2, 0x78, 0x71, 0x0c, 0xbe, 0x9d, 0x0b, 0xb6, 0x99, 0xfe,
- 0xc2, 0x17, 0x99, 0xcc, 0xac, 0x25, 0xcf, 0x16, 0x79, 0x24, 0x54, 0x93,
- 0x7e, 0x68, 0xbe, 0x68, 0xa9, 0x93, 0x55, 0xbc, 0x8e, 0xb2, 0xaf, 0x92,
- 0x51, 0xd3, 0xaf, 0x20, 0x30, 0xeb, 0x4d, 0xba, 0x23, 0x7a, 0x73, 0xc1,
- 0xaf, 0x90, 0x59, 0xe7, 0x32, 0x91, 0x7c, 0xd2, 0x80, 0x2f, 0xf7, 0x11,
- 0x80, 0x75, 0xf6, 0x3a, 0xf2, 0x4e, 0x9f, 0x8e, 0xad, 0xd1, 0x1e, 0xc9,
- 0xcf, 0xcd, 0x2f, 0xd9, 0x8c, 0xc7, 0x93, 0xae, 0xf5, 0xce, 0xbf, 0xbb,
- 0x03, 0xe5, 0xfd, 0x3a, 0xe8, 0xe9, 0xd6, 0x43, 0xa4, 0x5a, 0xda, 0x47,
- 0x59, 0x67, 0x5d, 0x3d, 0x32, 0x22, 0x5f, 0xa2, 0xdc, 0x43, 0x81, 0xef,
- 0x22, 0x17, 0xfd, 0xc7, 0x5e, 0x32, 0xe3, 0xb1, 0xd5, 0x88, 0x92, 0xf5,
- 0x6a, 0xff, 0xe1, 0x17, 0xd8, 0x71, 0x27, 0x3c, 0xf1, 0xd7, 0x9f, 0x7d,
- 0x1d, 0x50, 0x7c, 0x3a, 0x45, 0xbd, 0x1d, 0x73, 0xaf, 0xc9, 0x3d, 0x03,
- 0xe9, 0xd4, 0xd3, 0xc3, 0x58, 0xd5, 0xff, 0x79, 0x80, 0x6b, 0x16, 0xea,
- 0xe7, 0x5e, 0xcd, 0xd8, 0x3a, 0xf6, 0xfe, 0xe7, 0x4f, 0x64, 0x4f, 0x2f,
- 0xa7, 0x67, 0x5a, 0x75, 0xe0, 0x40, 0x9d, 0x48, 0x6f, 0x60, 0x8e, 0xff,
- 0xf9, 0xfc, 0x47, 0x7b, 0x1e, 0xbc, 0xcc, 0x30, 0xc1, 0xd4, 0xe9, 0xb0,
- 0x43, 0xde, 0x9c, 0x42, 0x3f, 0x53, 0xeb, 0x6c, 0xa8, 0xe4, 0x1b, 0x1c,
- 0xb6, 0x32, 0xa0, 0x42, 0x77, 0x21, 0x27, 0x28, 0x43, 0x6e, 0x5c, 0x91,
- 0xfc, 0xab, 0x97, 0xb3, 0x0b, 0x9e, 0x9b, 0xae, 0x15, 0x9c, 0x21, 0x8a,
- 0x58, 0x0f, 0xa6, 0x43, 0x1a, 0x8e, 0xa1, 0x09, 0xf8, 0xf1, 0x2f, 0x90,
- 0x64, 0xe7, 0x5f, 0xff, 0xb5, 0xde, 0xa3, 0x3a, 0xeb, 0xfd, 0x24, 0x80,
- 0x3a, 0x96, 0x7e, 0x8c, 0x0f, 0xdf, 0xef, 0xb8, 0x65, 0xc4, 0xe9, 0xd7,
- 0xf2, 0xf4, 0x8a, 0x7d, 0x83, 0xaf, 0xcf, 0xbf, 0x1d, 0xa7, 0x50, 0xa2,
- 0x23, 0xc9, 0x92, 0xa2, 0xfb, 0xb7, 0xf9, 0xd7, 0xef, 0xc0, 0x87, 0x0e,
- 0xbf, 0xda, 0xc5, 0xa7, 0xf9, 0x07, 0x59, 0xf0, 0xfb, 0x44, 0x5f, 0xe4,
- 0xb7, 0xf6, 0xfa, 0x75, 0x5d, 0x73, 0xaf, 0xe6, 0x8a, 0x37, 0x98, 0x75,
- 0xfb, 0x64, 0xeb, 0xb4, 0xea, 0xe9, 0xe9, 0x09, 0x5d, 0xf6, 0x01, 0x14,
- 0x3a, 0xff, 0xdc, 0x7e, 0xfa, 0x38, 0xc4, 0x7a, 0x75, 0xec, 0xc6, 0x4e,
- 0xb6, 0x70, 0xf6, 0xbd, 0x3f, 0xbf, 0x83, 0xd0, 0xae, 0x04, 0xeb, 0xe5,
- 0xbe, 0x6c, 0x75, 0xfb, 0x27, 0x0b, 0xee, 0x75, 0x21, 0xe4, 0xe8, 0x86,
- 0xf9, 0xc7, 0xf2, 0x3a, 0xcf, 0x89, 0xbd, 0x74, 0x84, 0x5e, 0xf4, 0x51,
- 0xf7, 0x59, 0xe2, 0x1b, 0xfb, 0x58, 0xb4, 0xe3, 0x9d, 0x7b, 0x76, 0xe8,
- 0xeb, 0x3e, 0xe7, 0x91, 0xd2, 0xbb, 0xe0, 0xc7, 0x5a, 0x75, 0xf3, 0x86,
- 0x7e, 0xd1, 0x57, 0xe6, 0xcc, 0xc3, 0x0c, 0x1d, 0x42, 0x7a, 0x41, 0x26,
- 0xbe, 0x8f, 0xaf, 0xe7, 0x50, 0x11, 0x6b, 0x8e, 0x7e, 0x90, 0xd3, 0xae,
- 0x95, 0xa4, 0x2a, 0xd7, 0x0a, 0x08, 0x32, 0xf6, 0x3f, 0xb1, 0x85, 0x30,
- 0x61, 0xbb, 0x79, 0x5a, 0x56, 0xf9, 0xf4, 0xeb, 0xcd, 0x18, 0x3a, 0xdb,
- 0xab, 0x47, 0x8e, 0xe5, 0xb7, 0xf3, 0xf7, 0x67, 0xee, 0xc7, 0x5f, 0x83,
- 0xee, 0x0c, 0x8e, 0xbd, 0xd7, 0x64, 0xeb, 0xe4, 0x18, 0x64, 0xeb, 0xfd,
- 0xfc, 0xf2, 0xec, 0xa6, 0x8e, 0xa6, 0xa3, 0x17, 0xa5, 0xcb, 0x27, 0xe0,
- 0xe4, 0xe2, 0x0b, 0xfe, 0x74, 0xe3, 0xaf, 0x6c, 0x60, 0xeb, 0xf9, 0xf8,
- 0x9b, 0x40, 0x9d, 0x7f, 0xdb, 0x0e, 0x37, 0x99, 0xee, 0x8e, 0xbf, 0xf6,
- 0x0e, 0xed, 0xd7, 0x42, 0xfe, 0x9d, 0x7e, 0xcf, 0xeb, 0x14, 0x3a, 0x90,
- 0xf9, 0x96, 0x7f, 0x78, 0x0f, 0x38, 0xeb, 0xff, 0xec, 0x11, 0x76, 0x00,
- 0x2f, 0xbb, 0x50, 0x4e, 0xbf, 0xfd, 0x1e, 0x19, 0x6b, 0xf7, 0x6f, 0x0c,
- 0x67, 0x0e, 0xa0, 0x22, 0xe7, 0x83, 0xa2, 0x99, 0x7f, 0xcb, 0xe6, 0x7f,
- 0x03, 0xdd, 0x8e, 0xbf, 0xfe, 0xe3, 0xae, 0x4f, 0xfc, 0xec, 0xa2, 0x24,
- 0x68, 0xbe, 0x2f, 0x47, 0x76, 0x34, 0x5f, 0xf4, 0xe8, 0x83, 0x92, 0xd5,
- 0xef, 0x5d, 0x51, 0xd7, 0xff, 0xf3, 0x60, 0x12, 0xe2, 0x0e, 0x4e, 0x86,
- 0xe9, 0x00, 0x75, 0xff, 0x95, 0x26, 0x08, 0x14, 0x4c, 0xe9, 0xd7, 0xf4,
- 0x77, 0x76, 0xe7, 0xce, 0xbf, 0xf7, 0xf4, 0x9d, 0xf8, 0x86, 0x1a, 0x75,
- 0xe8, 0xdd, 0x51, 0xd7, 0xf4, 0x7f, 0x4f, 0x9b, 0x1d, 0x4e, 0x8b, 0x4c,
- 0x2d, 0x9c, 0x7a, 0xc0, 0xf5, 0xff, 0xda, 0xc1, 0xfe, 0xbc, 0xce, 0x7c,
- 0xdc, 0xeb, 0xfe, 0x63, 0xce, 0xda, 0xc5, 0xba, 0xb9, 0xd7, 0x93, 0x88,
- 0x75, 0xfb, 0x1b, 0xd0, 0x34, 0xeb, 0xff, 0xa7, 0x7d, 0x47, 0x16, 0xe7,
- 0x11, 0x67, 0x5d, 0xb7, 0xce, 0xbf, 0xd3, 0xb9, 0x0d, 0x7c, 0x13, 0xa9,
- 0xcf, 0x27, 0x05, 0xef, 0xec, 0x63, 0xcf, 0x23, 0xe7, 0x5f, 0xff, 0xbf,
- 0xe5, 0xaf, 0x39, 0x07, 0xde, 0xa3, 0xaf, 0x0a, 0xbe, 0xe7, 0x9d, 0xfe,
- 0x75, 0xed, 0x99, 0x57, 0x3a, 0xb6, 0x46, 0x66, 0x17, 0xc9, 0x5c, 0x24,
- 0xb7, 0x7f, 0x0e, 0xbf, 0x75, 0x36, 0x85, 0x9a, 0x61, 0x3b, 0xef, 0x85,
- 0xe0, 0xd3, 0x09, 0xdd, 0xeb, 0x9a, 0x81, 0x3b, 0xfc, 0x30, 0xa7, 0xdf,
- 0xbe, 0x9a, 0x81, 0x3b, 0xfd, 0xac, 0xe2, 0x68, 0x3b, 0x1a, 0x61, 0x3b,
- 0xb0, 0x06, 0x98, 0x4e, 0xe6, 0x18, 0x3c, 0xc2, 0x75, 0x89, 0xa5, 0xee,
- 0x68, 0x85, 0xab, 0x23, 0xd2, 0x04, 0xe4, 0x06, 0x08, 0xad, 0xf2, 0xcc,
- 0x26, 0x98, 0xf9, 0xec, 0x9b, 0xa7, 0xee, 0xc4, 0x78, 0xf4, 0xeb, 0x8b,
- 0xe8, 0x7f, 0xc1, 0xa8, 0x27, 0x18, 0x47, 0x6a, 0x1d, 0x9f, 0x94, 0x69,
- 0x78, 0x7d, 0x59, 0xd7, 0xfc, 0xe1, 0xf8, 0xa4, 0xef, 0x2b, 0x3a, 0xf0,
- 0xe6, 0xb0, 0xf5, 0xfa, 0x39, 0x78, 0x1e, 0xb2, 0x75, 0x3b, 0x27, 0xbb,
- 0x68, 0x4f, 0x82, 0x1b, 0x58, 0x5f, 0x28, 0x5e, 0x21, 0x13, 0x23, 0xdd,
- 0x5a, 0xe4, 0x3c, 0xb4, 0x7d, 0xf9, 0xca, 0x69, 0xd0, 0xcb, 0xf2, 0x63,
- 0x7e, 0x06, 0x75, 0x14, 0x3a, 0xfe, 0xe3, 0xf9, 0x1d, 0xfd, 0x3a, 0xfe,
- 0x7f, 0xe3, 0x28, 0xb3, 0xaf, 0xcf, 0x39, 0xc7, 0xe7, 0x5f, 0x92, 0x77,
- 0xd3, 0x63, 0xaf, 0xd0, 0xdf, 0xe4, 0x8e, 0xbf, 0x0e, 0x79, 0xc6, 0x4e,
- 0xbf, 0xfd, 0x9e, 0xeb, 0x89, 0xe3, 0x76, 0xbe, 0x6c, 0x75, 0xff, 0x72,
- 0x17, 0xc4, 0x7d, 0xda, 0x75, 0xfd, 0xe4, 0x5b, 0x3d, 0x1b, 0x1d, 0x4d,
- 0x45, 0xba, 0x26, 0xfa, 0x71, 0x5b, 0x27, 0x62, 0x02, 0xc9, 0x13, 0xf4,
- 0xa4, 0x49, 0xbf, 0x0d, 0xfb, 0xff, 0x64, 0x71, 0x94, 0x1e, 0x66, 0xe7,
- 0x5f, 0x0b, 0xe3, 0x07, 0x53, 0xb3, 0x8e, 0x76, 0x4c, 0x01, 0xc6, 0x52,
- 0x86, 0x52, 0x1b, 0x4a, 0xe4, 0xf1, 0x1f, 0x08, 0xae, 0xce, 0x3d, 0xbf,
- 0xfe, 0x41, 0xc5, 0xbf, 0x91, 0x0b, 0x47, 0x16, 0x75, 0xff, 0x71, 0x1b,
- 0xc8, 0x6a, 0x2c, 0xeb, 0xff, 0x69, 0x07, 0x76, 0xfd, 0x34, 0x87, 0x56,
- 0x1f, 0xa7, 0xcd, 0xef, 0xda, 0x5b, 0x81, 0xce, 0xa6, 0xa6, 0x10, 0xb8,
- 0x60, 0xfc, 0x86, 0xff, 0xee, 0xad, 0xf3, 0xfe, 0x7d, 0xf5, 0xf7, 0x3a,
- 0xff, 0xff, 0xf7, 0x21, 0x3e, 0xd0, 0x8f, 0xf5, 0xc8, 0x6f, 0x91, 0x79,
- 0x75, 0xda, 0x75, 0xff, 0xb5, 0xe7, 0xe8, 0x21, 0x6e, 0x68, 0xea, 0x57,
- 0x45, 0xb7, 0x1d, 0xef, 0xff, 0xec, 0xdf, 0x35, 0x03, 0xc4, 0x7f, 0xf0,
- 0x30, 0xb3, 0xa9, 0xd3, 0x7c, 0x88, 0x7f, 0x09, 0x35, 0xfc, 0x21, 0x5a,
- 0x71, 0xce, 0xbf, 0xff, 0x40, 0xfe, 0x23, 0x82, 0xff, 0xd3, 0x19, 0xc3,
- 0xaf, 0xfd, 0xb4, 0x0e, 0xbf, 0xc4, 0x7d, 0x1d, 0x7b, 0xba, 0xd1, 0xe2,
- 0x03, 0xbf, 0xfd, 0xd7, 0xe3, 0xf8, 0xce, 0xca, 0x22, 0x46, 0x88, 0x0e,
- 0x63, 0x53, 0x50, 0x8c, 0xdf, 0x2c, 0xd5, 0xea, 0x68, 0x7f, 0x8c, 0x7e,
- 0xf4, 0xe7, 0xe1, 0xd5, 0x89, 0xdb, 0x24, 0x6d, 0xde, 0x4a, 0xef, 0x72,
- 0x15, 0xce, 0xbe, 0x7f, 0x67, 0xb0, 0xea, 0xf4, 0xf0, 0xbe, 0x3d, 0x7c,
- 0x3f, 0xf4, 0x27, 0x5f, 0x96, 0xad, 0x2b, 0x4a, 0xd2, 0xb2, 0x75, 0xff,
- 0xfc, 0xdc, 0xd2, 0x77, 0xa8, 0xbf, 0x3f, 0xe6, 0x31, 0xf3, 0xab, 0x11,
- 0x76, 0x84, 0x50, 0x79, 0x7f, 0xff, 0xd0, 0xdc, 0x16, 0x5b, 0x9b, 0xb7,
- 0xcb, 0xfb, 0x33, 0x0c, 0x30, 0x55, 0x3a, 0x6f, 0x3c, 0x86, 0xf0, 0x96,
- 0xdf, 0xbd, 0x7f, 0xe2, 0xb9, 0xd7, 0xf9, 0xf3, 0xb2, 0x88, 0x91, 0xa2,
- 0x09, 0xbf, 0xe7, 0xfe, 0x76, 0x51, 0x12, 0x34, 0x5f, 0x37, 0x87, 0x34,
- 0x04, 0x40, 0x48, 0xf6, 0x85, 0x1b, 0xb3, 0xa1, 0x55, 0x7f, 0xf3, 0xf1,
- 0x14, 0xce, 0xec, 0xb0, 0xee, 0x75, 0x21, 0xf7, 0xf0, 0xa6, 0xff, 0x07,
- 0x93, 0xdc, 0x49, 0x70, 0xeb, 0xff, 0x6d, 0x1b, 0xcf, 0x67, 0xc6, 0x27,
- 0x1d, 0x7f, 0xec, 0x03, 0xb5, 0xf9, 0x9e, 0xc1, 0xd7, 0x98, 0x61, 0x82,
- 0xaf, 0xdc, 0xc9, 0x47, 0x4a, 0x98, 0xbf, 0xbf, 0xff, 0xcc, 0xf5, 0xe7,
- 0x78, 0x52, 0x3c, 0x79, 0x67, 0x5e, 0x33, 0x7f, 0x9d, 0x5f, 0x45, 0x2f,
- 0x93, 0x6a, 0xd9, 0x36, 0x85, 0xa1, 0x8c, 0x60, 0x17, 0xfe, 0x5b, 0xef,
- 0xa1, 0xcd, 0xbc, 0xb4, 0xeb, 0xfc, 0xa7, 0x86, 0x5a, 0xfd, 0xd1, 0xd5,
- 0xb1, 0xfc, 0x22, 0x0d, 0xfc, 0xaf, 0x8d, 0xe3, 0xf4, 0xeb, 0xfd, 0xf7,
- 0x4e, 0x28, 0xfb, 0x9d, 0x7f, 0xfb, 0x71, 0xf1, 0x2e, 0x27, 0xbe, 0xbf,
- 0x5a, 0x75, 0x3a, 0x2c, 0x10, 0xbf, 0xc9, 0x9d, 0xfa, 0x15, 0xf4, 0xd9,
- 0xc7, 0x5f, 0xf8, 0x3a, 0x7c, 0x1f, 0xcf, 0xac, 0x48, 0xeb, 0xff, 0xfe,
- 0xd6, 0xd8, 0xc0, 0xe0, 0x3a, 0x81, 0xd8, 0x1c, 0x71, 0xd8, 0xeb, 0xcc,
- 0x30, 0xc1, 0x57, 0xfb, 0xcf, 0xae, 0x39, 0xbf, 0xca, 0x98, 0xbf, 0xbf,
- 0xff, 0xa7, 0xef, 0x12, 0xe2, 0x00, 0x18, 0xc7, 0x8f, 0xeb, 0x36, 0x3a,
- 0xb8, 0x8a, 0xb0, 0xa2, 0xd2, 0x26, 0xab, 0x11, 0x99, 0x53, 0x57, 0x57,
- 0x00, 0x42, 0x91, 0xcf, 0x76, 0x15, 0xeb, 0x86, 0x97, 0x0c, 0x04, 0xb3,
- 0xf1, 0xcc, 0x5f, 0xfb, 0x10, 0x76, 0x81, 0xfe, 0x2c, 0xeb, 0xff, 0x71,
- 0x18, 0x07, 0x33, 0xf3, 0xd8, 0x75, 0xf6, 0x7d, 0x96, 0x9d, 0x7f, 0xf2,
- 0xa1, 0x75, 0x5a, 0x81, 0xf3, 0xee, 0x8e, 0xae, 0x1f, 0x5c, 0x11, 0x5f,
- 0xfb, 0x3e, 0xfd, 0xd7, 0x1c, 0x7e, 0x78, 0x82, 0x2f, 0xf3, 0xe7, 0x65,
- 0x11, 0x23, 0x44, 0x11, 0x31, 0xe4, 0xdf, 0xd1, 0xce, 0xf5, 0x18, 0x3a,
- 0xfe, 0x57, 0x03, 0x10, 0x2d, 0x3a, 0x84, 0xf7, 0x42, 0x5b, 0x5c, 0x4c,
- 0xdf, 0xd6, 0xa1, 0x85, 0x65, 0xfd, 0xcc, 0xff, 0xd1, 0x67, 0x5f, 0xdf,
- 0xf3, 0x9c, 0x8d, 0xce, 0xad, 0xcf, 0x6c, 0x4b, 0x2f, 0xff, 0x6b, 0x43,
- 0x1f, 0x85, 0xf9, 0x7d, 0xb0, 0xea, 0x73, 0xec, 0x09, 0x15, 0xce, 0xa1,
- 0xd7, 0xfe, 0xce, 0x3a, 0x7c, 0x73, 0x88, 0x75, 0xd0, 0xc7, 0x83, 0xd0,
- 0xf8, 0xb5, 0x35, 0x14, 0x22, 0xe3, 0x7f, 0xdc, 0x7e, 0xfc, 0x5f, 0x37,
- 0x3a, 0xff, 0xff, 0x93, 0x67, 0x6e, 0xbb, 0xd4, 0xdd, 0x96, 0xc7, 0x57,
- 0x9b, 0x9d, 0x7d, 0xfe, 0x60, 0x81, 0x14, 0x1c, 0x37, 0xbf, 0xf4, 0xb8,
- 0xf9, 0xd6, 0xe8, 0x2b, 0x3a, 0xfe, 0xf2, 0xbd, 0x31, 0x1b, 0x9d, 0x4e,
- 0x8a, 0x8c, 0x39, 0xf9, 0xf5, 0xee, 0xe7, 0x0e, 0xbd, 0xa4, 0x59, 0xd6,
- 0x7e, 0x9b, 0x6f, 0x8d, 0xdf, 0x23, 0x28, 0xc1, 0xd7, 0xff, 0x2e, 0x37,
- 0xf3, 0xf4, 0xeb, 0x86, 0x7e, 0x3a, 0xff, 0xfc, 0x1d, 0x85, 0xf3, 0x93,
- 0x3f, 0xf3, 0x81, 0xe9, 0xd7, 0xdf, 0xd7, 0x9d, 0x01, 0x18, 0x58, 0x45,
- 0xe5, 0x2e, 0xfd, 0xa5, 0xe7, 0xf4, 0x75, 0xfa, 0x1a, 0x28, 0xe7, 0x5f,
- 0xcf, 0x03, 0xfc, 0x13, 0xa9, 0xa9, 0xd3, 0xe4, 0x3a, 0x11, 0x2d, 0x64,
- 0xe2, 0x49, 0x7f, 0x4b, 0x89, 0x3c, 0x8a, 0x1d, 0x7f, 0xf9, 0x3d, 0x7d,
- 0x2d, 0xd3, 0xbd, 0x46, 0x0e, 0xbe, 0x57, 0xe6, 0x6c, 0x75, 0xfe, 0x70,
- 0x67, 0xd3, 0x81, 0x3a, 0xcb, 0x73, 0xd6, 0x01, 0x2d, 0xff, 0xff, 0x97,
- 0x03, 0xeb, 0x53, 0x41, 0x5f, 0x11, 0xff, 0xc0, 0xc2, 0xce, 0xbb, 0xc2,
- 0xb9, 0xd7, 0xff, 0xe8, 0x4f, 0xa0, 0x30, 0x19, 0xf4, 0x5a, 0x74, 0xeb,
- 0xdd, 0x8d, 0x74, 0xfb, 0x38, 0x37, 0x72, 0x7e, 0x13, 0x0a, 0x0c, 0x35,
- 0xef, 0x43, 0x5c, 0xea, 0x02, 0xa4, 0xdc, 0x30, 0x48, 0x4f, 0xc4, 0x66,
- 0x22, 0x67, 0x7f, 0x75, 0xf6, 0x41, 0xf9, 0xd7, 0xe1, 0x70, 0x63, 0x27,
- 0x5f, 0x68, 0x3d, 0x50, 0xeb, 0xf3, 0xf3, 0xee, 0xd3, 0xaf, 0x80, 0x1f,
- 0xe9, 0xcf, 0xbf, 0x72, 0x6f, 0x48, 0xef, 0xde, 0xe2, 0xdf, 0x87, 0x50,
- 0x13, 0x0a, 0x48, 0x4d, 0x8a, 0x45, 0xee, 0xf9, 0xd1, 0xd7, 0x3a, 0xb6,
- 0x3a, 0xff, 0xd0, 0x32, 0xce, 0xca, 0x22, 0x46, 0x88, 0x46, 0x9d, 0x10,
- 0x3e, 0x8f, 0x04, 0x6e, 0xff, 0xf3, 0xe6, 0xfe, 0x7e, 0x82, 0x16, 0xe6,
- 0x8e, 0xbf, 0xfb, 0xf0, 0x3b, 0x6e, 0xd1, 0x7c, 0xd1, 0xd7, 0xfe, 0xf3,
- 0x9c, 0x85, 0xcc, 0xc3, 0x0c, 0x1d, 0x7f, 0xfe, 0xc9, 0x71, 0xc4, 0x02,
- 0x9b, 0x60, 0xa2, 0x87, 0x5d, 0x11, 0xb2, 0x25, 0x9a, 0x89, 0x7f, 0xf7,
- 0xf8, 0x93, 0xb9, 0x0d, 0xeb, 0xa8, 0x75, 0xfd, 0x8c, 0x60, 0x87, 0xd3,
- 0xaf, 0xcd, 0xcf, 0xbf, 0xa7, 0x5c, 0xeb, 0xd8, 0xf5, 0x37, 0x2d, 0xbf,
- 0xff, 0xfb, 0xd5, 0xc3, 0x79, 0x09, 0xf4, 0x06, 0x03, 0x3e, 0x8b, 0x4e,
- 0x9d, 0x5a, 0x44, 0xf0, 0x4b, 0xef, 0xdb, 0x2d, 0xc0, 0xe7, 0x50, 0x15,
- 0x69, 0xee, 0x94, 0xcc, 0x36, 0x78, 0x5d, 0xf8, 0xce, 0x3c, 0x91, 0xdf,
- 0xf0, 0x1f, 0x5a, 0x7d, 0xb1, 0x83, 0xab, 0x11, 0x43, 0x0d, 0x17, 0x98,
- 0x61, 0x82, 0xaf, 0xfb, 0x3d, 0x8e, 0xe4, 0xec, 0x01, 0x53, 0x17, 0xf7,
- 0x30, 0xc1, 0x57, 0x98, 0x61, 0x82, 0xaf, 0xe8, 0xd8, 0x1c, 0x7d, 0x15,
- 0x31, 0x7f, 0x42, 0x8b, 0xd6, 0x12, 0x67, 0x8d, 0xef, 0xd2, 0x40, 0x79,
- 0x59, 0x53, 0x1b, 0x3b, 0xcc, 0x30, 0xc1, 0x57, 0xb4, 0xfd, 0x2a, 0x62,
- 0xfe, 0xfa, 0x07, 0x7f, 0x9d, 0x6f, 0x51, 0x14, 0xbf, 0x59, 0x60, 0xae,
- 0xfe, 0x00, 0xbb, 0x62, 0x47, 0x5f, 0xb4, 0x1d, 0xa7, 0x84, 0xeb, 0xf0,
- 0x12, 0x73, 0x80, 0xeb, 0xec, 0x1c, 0x57, 0x3a, 0xba, 0x79, 0x4b, 0x28,
- 0xa4, 0x44, 0xbf, 0x97, 0x5b, 0xff, 0xb9, 0x0d, 0x18, 0x51, 0x91, 0x46,
- 0x4e, 0xbf, 0xb9, 0x93, 0xb3, 0xfa, 0x3a, 0xa4, 0x7e, 0x5f, 0x44, 0xae,
- 0xa6, 0xf5, 0xc8, 0x61, 0x0c, 0x25, 0xa9, 0xd3, 0xeb, 0xc8, 0xec, 0x6f,
- 0x6e, 0xad, 0xca, 0xc9, 0xd7, 0xff, 0xb1, 0x5e, 0x07, 0xdc, 0x93, 0xf1,
- 0xd6, 0x75, 0xfd, 0x24, 0xd7, 0x11, 0x92, 0xaf, 0xf0, 0xe6, 0xed, 0xd2,
- 0x28, 0x75, 0xf4, 0x47, 0x54, 0x3a, 0xbc, 0x1e, 0xa6, 0xc6, 0x77, 0xfd,
- 0x99, 0x2f, 0x5f, 0x37, 0x69, 0xd7, 0xcf, 0x0b, 0x9c, 0x55, 0xfd, 0xcc,
- 0x5a, 0xe1, 0xa7, 0x5e, 0x61, 0x86, 0x0a, 0xbf, 0xc3, 0xfe, 0x23, 0x8e,
- 0xc5, 0x4c, 0x5f, 0xdf, 0x79, 0x7f, 0x71, 0xa8, 0x8c, 0xc4, 0xbb, 0x64,
- 0x91, 0xd2, 0xb8, 0x57, 0x5f, 0xe7, 0xf3, 0xde, 0xa7, 0xf4, 0x75, 0x3a,
- 0xa9, 0xb6, 0x94, 0xee, 0x94, 0x90, 0x81, 0x64, 0x97, 0x91, 0x90, 0x89,
- 0x6d, 0xfb, 0xdc, 0x4e, 0x28, 0x75, 0xff, 0xf6, 0x49, 0xc6, 0x3f, 0xa0,
- 0x06, 0x3a, 0xd3, 0xab, 0x73, 0xf5, 0x59, 0x45, 0xe9, 0x3e, 0x8e, 0xbf,
- 0xfb, 0xcb, 0x73, 0x91, 0xc4, 0xef, 0x5c, 0xea, 0xc3, 0xdf, 0xf4, 0x6e,
- 0xfc, 0xff, 0xd4, 0xec, 0x3a, 0xfc, 0x1e, 0xa9, 0xc4, 0x3a, 0x9d, 0x1e,
- 0x83, 0x08, 0x2f, 0x91, 0x4f, 0x14, 0x5f, 0xff, 0x24, 0xec, 0x10, 0x0c,
- 0x31, 0x83, 0x0a, 0x1d, 0x7f, 0xff, 0xc0, 0xe2, 0x31, 0x8a, 0x91, 0x71,
- 0xfd, 0x05, 0xb9, 0xbf, 0xce, 0xac, 0x45, 0xbc, 0x27, 0x5f, 0xb6, 0xf0,
- 0x17, 0x64, 0xeb, 0x9a, 0xd3, 0xaa, 0x0f, 0x07, 0x45, 0x74, 0xee, 0x99,
- 0x2f, 0x68, 0xec, 0x9b, 0x1f, 0x48, 0x23, 0xf2, 0xc9, 0xed, 0xc5, 0x21,
- 0x11, 0x23, 0xb4, 0x8f, 0x8d, 0x98, 0xe7, 0xbb, 0x1b, 0x52, 0xe5, 0x05,
- 0xf2, 0x54, 0xd4, 0x46, 0xbb, 0xec, 0x2d, 0x46, 0x5d, 0x26, 0xa5, 0xe0,
- 0x7e, 0x56, 0x18, 0x63, 0xd9, 0x62, 0x1f, 0x5e, 0x58, 0xaf, 0x4e, 0x71,
- 0x3a, 0xff, 0xfb, 0x06, 0x6f, 0xa8, 0x9b, 0xeb, 0x99, 0xec, 0x1d, 0x4d,
- 0x3e, 0xd0, 0x0e, 0x5f, 0xe8, 0x19, 0x67, 0xf8, 0x87, 0x56, 0xe7, 0xa4,
- 0xb2, 0x2b, 0x95, 0xbd, 0x5b, 0x1d, 0x79, 0xc7, 0x63, 0xaf, 0x93, 0x88,
- 0xb3, 0xad, 0xc4, 0x37, 0x6c, 0x8d, 0xdf, 0xf8, 0x5f, 0xfc, 0x8f, 0x63,
- 0x7d, 0x1d, 0x79, 0x90, 0xf4, 0xeb, 0xff, 0x42, 0x77, 0x37, 0x99, 0x86,
- 0x18, 0x3a, 0xa0, 0xf7, 0xf4, 0x3b, 0x7f, 0xfc, 0x2e, 0xdf, 0x1e, 0x7e,
- 0x82, 0x16, 0xe6, 0x8e, 0xac, 0x4c, 0xda, 0x44, 0xfc, 0x84, 0xef, 0xa4,
- 0x37, 0xf9, 0xc5, 0xa3, 0x99, 0xe9, 0xd7, 0xf6, 0x77, 0x42, 0xfb, 0x1d,
- 0x7f, 0x47, 0xf9, 0x03, 0xe9, 0xd7, 0xfe, 0x8f, 0xe3, 0x30, 0xe2, 0xec,
- 0x9d, 0x64, 0xe9, 0xf4, 0x70, 0xb2, 0x9a, 0x8b, 0xb9, 0x42, 0x52, 0xff,
- 0xfb, 0x3e, 0xe3, 0x2c, 0xff, 0x13, 0xbe, 0xc8, 0xeb, 0xfc, 0xeb, 0xd6,
- 0xa0, 0x76, 0x3a, 0xfd, 0x1a, 0xc1, 0xf9, 0xd7, 0xbf, 0x0a, 0xe7, 0x5f,
- 0xef, 0xf1, 0x26, 0xf6, 0x10, 0xea, 0x02, 0x3d, 0xb8, 0x9c, 0x26, 0x5f,
- 0x25, 0x08, 0xf5, 0xf7, 0x12, 0x1a, 0x75, 0xe0, 0x43, 0x4e, 0xb8, 0x3e,
- 0xb9, 0xbb, 0xc2, 0x0b, 0xfe, 0x96, 0x7d, 0xe7, 0x20, 0xfa, 0x75, 0xff,
- 0xfc, 0x17, 0xfe, 0xb0, 0x7c, 0x75, 0xd0, 0x03, 0x0d, 0x3a, 0xfd, 0x2e,
- 0x6f, 0x0a, 0xe7, 0x52, 0x22, 0xf4, 0x4e, 0x42, 0xb3, 0x7f, 0xff, 0x0e,
- 0x68, 0x3e, 0x33, 0x90, 0x38, 0xcb, 0x5f, 0x73, 0xaf, 0xfd, 0x9a, 0x0e,
- 0x76, 0x51, 0x12, 0x34, 0x40, 0xd7, 0xdf, 0xe4, 0x37, 0xc2, 0x29, 0x05,
- 0x6e, 0xff, 0x87, 0xdf, 0xa6, 0xcb, 0x79, 0x1d, 0x7e, 0x04, 0xf9, 0x00,
- 0x9f, 0x0e, 0xa7, 0x4d, 0xdf, 0x21, 0xa4, 0x87, 0x70, 0x73, 0x7f, 0xb3,
- 0x7f, 0x83, 0x31, 0x43, 0xaf, 0xec, 0xfb, 0x8a, 0x7a, 0x75, 0xff, 0xa3,
- 0xb8, 0x3e, 0xeb, 0xfa, 0xdc, 0xeb, 0xff, 0xff, 0xfb, 0x3f, 0xc8, 0x15,
- 0x3c, 0x6b, 0xb1, 0x1f, 0x9d, 0x80, 0xf1, 0x8b, 0x81, 0xdd, 0xa7, 0x88,
- 0x2e, 0xff, 0xd1, 0x0a, 0x4a, 0x01, 0xe1, 0x46, 0x0f, 0x10, 0x5d, 0xff,
- 0xdc, 0x4e, 0x23, 0x8f, 0xfc, 0x28, 0xc1, 0xe2, 0x0b, 0xbf, 0xce, 0x83,
- 0xff, 0x0a, 0x30, 0x78, 0x82, 0xef, 0xe5, 0xe0, 0x3c, 0x28, 0xc1, 0xe2,
- 0x0b, 0xbf, 0xff, 0xe8, 0x11, 0x45, 0xf8, 0xd4, 0xb8, 0x9d, 0x45, 0x36,
- 0xc6, 0x0f, 0x10, 0x5d, 0xdb, 0xf8, 0x02, 0x72, 0xf2, 0x4f, 0xea, 0x9c,
- 0x21, 0x09, 0xf5, 0x3a, 0xac, 0x8e, 0x1f, 0x8c, 0xa3, 0x1b, 0xfc, 0x8e,
- 0xa6, 0xbf, 0xad, 0xce, 0xbe, 0x8e, 0xfb, 0x07, 0x5f, 0xfd, 0xc4, 0xe2,
- 0x38, 0xff, 0xc2, 0x8c, 0x1e, 0x20, 0xbb, 0xfe, 0x67, 0x52, 0x4d, 0xbc,
- 0x28, 0xc1, 0xe2, 0x0b, 0xbf, 0x7f, 0x4e, 0xbf, 0x12, 0x44, 0xff, 0x95,
- 0x3b, 0xff, 0xde, 0x25, 0xc4, 0x93, 0xff, 0x5e, 0x14, 0x60, 0xf1, 0x05,
- 0xdf, 0xff, 0xfc, 0x22, 0x8b, 0xf0, 0x1c, 0xf1, 0xa9, 0x71, 0x3a, 0x8a,
- 0x6d, 0x8c, 0x1e, 0x20, 0xba, 0xc4, 0xc9, 0x37, 0x44, 0x85, 0xdb, 0xfe,
- 0xe2, 0x75, 0x14, 0xdb, 0x18, 0x3c, 0x41, 0x77, 0xff, 0xd1, 0x1b, 0xb7,
- 0x5c, 0x40, 0x01, 0xfa, 0xe5, 0x5f, 0xfb, 0x1a, 0xd0, 0xeb, 0xa3, 0xb4,
- 0xf1, 0xe2, 0x0b, 0xa9, 0x23, 0x93, 0xa8, 0xfa, 0x4e, 0xbf, 0xf4, 0x93,
- 0xbf, 0x8f, 0x75, 0xe1, 0x83, 0xc4, 0x17, 0x7f, 0x71, 0x39, 0xc4, 0xf4,
- 0xd0, 0x05, 0xdf, 0xb3, 0xdf, 0x0a, 0x30, 0x78, 0x82, 0xee, 0xcf, 0xc8,
- 0xfc, 0xf8, 0x75, 0x5b, 0xa3, 0xbf, 0x50, 0xc2, 0xbf, 0x97, 0x80, 0xf0,
- 0xa3, 0x07, 0x88, 0x2e, 0xff, 0xd2, 0xe2, 0x75, 0x14, 0xdb, 0x18, 0x3c,
- 0x41, 0x77, 0x67, 0x88, 0x44, 0x5e, 0x8f, 0xaf, 0xf0, 0x51, 0x70, 0x3b,
- 0xb4, 0xf1, 0x05, 0xdf, 0xfb, 0x12, 0x76, 0x0e, 0x02, 0x1a, 0x78, 0x82,
- 0xd6, 0x6f, 0xe8, 0x0b, 0xbf, 0xbd, 0x37, 0xf4, 0xd0, 0x63, 0xe4, 0xd4,
- 0x62, 0x9f, 0x8c, 0x7c, 0x30, 0xb4, 0x61, 0xba, 0xef, 0x5c, 0xd1, 0x05,
- 0xcc, 0x88, 0xcb, 0xa2, 0x47, 0x5b, 0x5e, 0x9e, 0x5f, 0xcd, 0xae, 0x6a,
- 0xa3, 0xaf, 0x3b, 0x55, 0x1d, 0x4e, 0x6d, 0x44, 0x62, 0xb6, 0x65, 0x3b,
- 0x80, 0xcf, 0xda, 0x4e, 0x38, 0xaf, 0x5f, 0xfb, 0x1b, 0xc8, 0x6a, 0xa5,
- 0x41, 0xd8, 0xeb, 0xfa, 0x1a, 0xf3, 0xa3, 0x87, 0x5f, 0x6f, 0xa7, 0xdc,
- 0xeb, 0xcb, 0x76, 0x9d, 0x7e, 0xc0, 0x70, 0x2c, 0x1d, 0x5e, 0x0f, 0x9a,
- 0x08, 0xc4, 0x6e, 0xf0, 0x23, 0xe7, 0x57, 0x4f, 0x2a, 0x0b, 0xef, 0x24,
- 0xf6, 0x1d, 0x7a, 0x3b, 0xe9, 0xd6, 0xdd, 0xcd, 0xcf, 0xc7, 0x6f, 0x98,
- 0xce, 0x41, 0xd7, 0xca, 0x75, 0x18, 0x3a, 0xfd, 0xb4, 0x71, 0xd5, 0xce,
- 0xa5, 0x64, 0xf3, 0x70, 0x8e, 0x9d, 0x3f, 0x24, 0x86, 0xec, 0x2d, 0x7a,
- 0x4e, 0x2d, 0xd7, 0xff, 0xd8, 0x22, 0xfb, 0x2f, 0x89, 0xde, 0xc3, 0x4e,
- 0xbd, 0x1d, 0xd8, 0xeb, 0xbd, 0x73, 0xaf, 0x91, 0xd7, 0x87, 0x51, 0xd7,
- 0xf4, 0x29, 0xf7, 0xef, 0xa7, 0x50, 0x0d, 0xc0, 0x85, 0x5f, 0xff, 0xe7,
- 0x40, 0x0b, 0x86, 0x5f, 0xc9, 0x01, 0xe5, 0xe5, 0x67, 0x5d, 0xeb, 0x9d,
- 0x73, 0xa8, 0x75, 0xff, 0x67, 0xf4, 0xeb, 0xf3, 0x8c, 0x9d, 0x7f, 0xb5,
- 0x9c, 0x4d, 0x07, 0x63, 0xae, 0x61, 0x82, 0xaf, 0xf8, 0x72, 0x74, 0x37,
- 0x48, 0x03, 0xaa, 0x49, 0xf9, 0x20, 0xe7, 0x45, 0x96, 0xaf, 0xc2, 0x0f,
- 0x58, 0x27, 0xe1, 0x61, 0x16, 0xd1, 0xd3, 0x06, 0x7e, 0x46, 0x2f, 0x30,
- 0xc3, 0x05, 0x59, 0x65, 0x4c, 0x5f, 0xdf, 0xa1, 0x98, 0x8e, 0x95, 0x32,
- 0x37, 0xfc, 0xc2, 0xfe, 0xfe, 0xfb, 0xe7, 0x33, 0x63, 0xae, 0xc5, 0x9d,
- 0x5b, 0x9e, 0x0e, 0x8b, 0x29, 0xdb, 0x83, 0x96, 0x91, 0xe4, 0x72, 0x8a,
- 0x21, 0xef, 0x0e, 0xb4, 0x8c, 0x7b, 0xb0, 0x84, 0xe4, 0xa6, 0x08, 0xa5,
- 0x5b, 0x0a, 0x5e, 0xa5, 0x1a, 0xfd, 0x34, 0x32, 0xc7, 0xa7, 0x42, 0x3a,
- 0xf4, 0x4b, 0x0e, 0xbb, 0x18, 0x3a, 0xe7, 0xf9, 0xd5, 0xb1, 0xab, 0x90,
- 0xb5, 0x96, 0x75, 0x61, 0xb2, 0xf9, 0x15, 0xfc, 0xb7, 0xdb, 0xf9, 0x23,
- 0xaf, 0xb1, 0x79, 0xf3, 0xaf, 0x7e, 0x14, 0x3a, 0xff, 0xff, 0xe9, 0x43,
- 0x21, 0x68, 0x65, 0xe3, 0x89, 0xff, 0xbe, 0xef, 0xb3, 0xe8, 0xeb, 0xff,
- 0xfe, 0x57, 0x18, 0x89, 0xce, 0xde, 0x3f, 0x76, 0x7f, 0xea, 0x1a, 0x75,
- 0xe4, 0xdd, 0x93, 0xaf, 0xd9, 0x9b, 0x07, 0x47, 0x5f, 0x74, 0x53, 0xd3,
- 0xaf, 0xfc, 0x1d, 0x83, 0x37, 0x12, 0x51, 0xd3, 0xa9, 0x0f, 0x87, 0x84,
- 0x37, 0xfd, 0xc8, 0xd7, 0x13, 0x68, 0x13, 0xaf, 0xa3, 0x6f, 0x2d, 0x3a,
- 0xa7, 0xf5, 0x60, 0x0e, 0xef, 0xb1, 0x06, 0xe5, 0xa8, 0x41, 0xd1, 0xc8,
- 0x76, 0xf5, 0xa7, 0x43, 0xbf, 0x84, 0x47, 0x92, 0x15, 0x46, 0xf7, 0xf0,
- 0x84, 0x0b, 0x86, 0x9d, 0x7f, 0xf9, 0xa2, 0xfe, 0x16, 0x2e, 0xa7, 0xd3,
- 0x63, 0xaf, 0xd0, 0xbc, 0xe2, 0xce, 0xad, 0xcf, 0xc7, 0xe9, 0x77, 0xbf,
- 0xd7, 0x3a, 0xff, 0x6b, 0xf3, 0xb0, 0x70, 0x07, 0x53, 0xa6, 0x1c, 0x90,
- 0x9d, 0x59, 0x1c, 0x0d, 0xde, 0x8f, 0x1e, 0x4e, 0xbe, 0x5a, 0xdd, 0x67,
- 0x5f, 0xff, 0x0b, 0x7c, 0x60, 0x13, 0x5b, 0xfc, 0x31, 0xa3, 0xaf, 0xca,
- 0x6b, 0x48, 0xc9, 0xd7, 0xff, 0x46, 0xc2, 0xfb, 0xa0, 0x05, 0xf6, 0x3a,
- 0xba, 0x7d, 0x82, 0x53, 0x7e, 0xf1, 0xc7, 0xeb, 0x4e, 0xaf, 0x09, 0xa3,
- 0xb8, 0xfe, 0x10, 0xc4, 0x2f, 0x58, 0x21, 0xbc, 0xbd, 0x39, 0xd7, 0xf6,
- 0xcc, 0xb6, 0x7f, 0xee, 0xc7, 0x5f, 0x2f, 0x23, 0x87, 0x5c, 0xdd, 0x8e,
- 0xbf, 0x73, 0x11, 0xba, 0x3a, 0xff, 0xfb, 0x8f, 0xe6, 0x6f, 0x8c, 0x7b,
- 0xad, 0x3f, 0xa5, 0x5f, 0xbb, 0x28, 0x89, 0x1e, 0x20, 0x4b, 0xda, 0x7d,
- 0xce, 0xb7, 0xb8, 0x79, 0xfb, 0x99, 0xde, 0xfa, 0x6c, 0x75, 0xed, 0xa0,
- 0x4e, 0xa6, 0xa6, 0x50, 0x02, 0x6e, 0xc2, 0x89, 0x65, 0x3f, 0x1c, 0xbf,
- 0x86, 0x50, 0xa7, 0x10, 0xeb, 0x95, 0x34, 0xeb, 0xef, 0xed, 0x02, 0x75,
- 0xe1, 0x85, 0x0e, 0xbe, 0xdf, 0x51, 0xf3, 0xaf, 0xe5, 0xfd, 0x00, 0x17,
- 0x3a, 0xf2, 0xff, 0x23, 0xad, 0xf7, 0x3c, 0x8c, 0x2c, 0xad, 0x91, 0xc9,
- 0x83, 0x12, 0x21, 0xe0, 0xd8, 0xb5, 0x5d, 0xd0, 0x9d, 0x7f, 0x86, 0x18,
- 0xd6, 0x9f, 0xd3, 0xaf, 0x4f, 0x42, 0x87, 0x5f, 0xf3, 0xad, 0xb9, 0xb6,
- 0x06, 0x7e, 0x3a, 0xb0, 0xf7, 0x10, 0x7e, 0xf3, 0x0c, 0x30, 0x7a, 0xbe,
- 0xaf, 0x40, 0x80, 0xb5, 0x7d, 0x26, 0x35, 0x97, 0xec, 0x68, 0x5d, 0x43,
- 0xa9, 0xd3, 0x51, 0x00, 0xb7, 0x61, 0x1f, 0xea, 0x67, 0xce, 0x6f, 0xff,
- 0xd8, 0x28, 0xa4, 0xda, 0xff, 0x03, 0x0d, 0x6b, 0x9d, 0x5b, 0x22, 0x95,
- 0x45, 0x0b, 0xec, 0x04, 0x34, 0xeb, 0xf4, 0x08, 0xa2, 0xce, 0xbf, 0xee,
- 0x27, 0x71, 0x16, 0xea, 0xe7, 0x5f, 0x91, 0x70, 0x38, 0x75, 0x78, 0x5e,
- 0x15, 0x56, 0x86, 0xdc, 0xd9, 0xa4, 0x19, 0x19, 0xfa, 0x8a, 0x09, 0x18,
- 0x84, 0x4a, 0x3f, 0xf4, 0x94, 0x48, 0x02, 0x49, 0x3c, 0x73, 0x7e, 0x4f,
- 0xbf, 0xf4, 0x55, 0xf4, 0x9f, 0xfa, 0x2a, 0xe6, 0x18, 0x2a, 0x9a, 0x7b,
- 0xf8, 0x4c, 0xc1, 0x0d, 0xd8, 0xc1, 0x53, 0x1a, 0xfb, 0xff, 0xf6, 0x7d,
- 0xe5, 0x98, 0x3f, 0xe2, 0x38, 0xec, 0x75, 0x7a, 0x7f, 0x0c, 0x13, 0xdf,
- 0xff, 0xe7, 0x9c, 0x83, 0xef, 0x8f, 0xeb, 0x25, 0xc8, 0x1f, 0xe8, 0xeb,
- 0xf3, 0x78, 0x17, 0xe9, 0xd7, 0xff, 0x42, 0xfa, 0xf3, 0x92, 0x70, 0x87,
- 0x47, 0x56, 0xe7, 0xdb, 0xc2, 0x7b, 0xf6, 0x05, 0x6f, 0xa3, 0xa8, 0xeb,
- 0xd9, 0x8c, 0xf4, 0xd8, 0x68, 0x9a, 0x99, 0x44, 0x2f, 0x54, 0xef, 0x36,
- 0x3a, 0x75, 0xf9, 0xb9, 0xfc, 0x01, 0x57, 0xce, 0x22, 0xe7, 0x59, 0x19,
- 0x3d, 0xff, 0x8d, 0xf9, 0x26, 0xbf, 0xe1, 0xce, 0x67, 0x8e, 0x66, 0xc7,
- 0x5f, 0xc1, 0x9f, 0x93, 0xbd, 0xc3, 0xaf, 0xbe, 0xa6, 0x70, 0xeb, 0xfb,
- 0xd0, 0xeb, 0xc2, 0x7a, 0x75, 0xde, 0xb9, 0xd7, 0x7a, 0xe7, 0x5f, 0x82,
- 0xdc, 0x19, 0x90, 0xd6, 0x7a, 0x2d, 0x4e, 0x8b, 0xdf, 0x48, 0x85, 0x76,
- 0xff, 0xfb, 0x06, 0x37, 0xd2, 0x8a, 0x47, 0x89, 0x2f, 0xd3, 0xaf, 0xfe,
- 0xff, 0x31, 0x7e, 0x5f, 0xdc, 0xdf, 0xe7, 0x5f, 0xed, 0xe4, 0x9d, 0xf2,
- 0xe0, 0x3a, 0xfb, 0xd5, 0xc3, 0x7c, 0x23, 0x43, 0x4a, 0x9f, 0x47, 0xbf,
- 0xbd, 0x5f, 0x9d, 0x79, 0xd8, 0xeb, 0xb3, 0x73, 0xab, 0x73, 0xca, 0x9e,
- 0x34, 0xbe, 0xf7, 0xa9, 0xd3, 0xa9, 0xd1, 0xb9, 0x10, 0x94, 0x60, 0x9a,
- 0xfb, 0x41, 0xdf, 0xe7, 0x5e, 0xee, 0x30, 0x75, 0xff, 0x99, 0x7d, 0xb5,
- 0xdc, 0x93, 0xec, 0x75, 0xfe, 0x5e, 0x2f, 0x00, 0x8c, 0x1d, 0x7f, 0x0e,
- 0x33, 0xc4, 0xf9, 0xd7, 0xd9, 0x9c, 0xd1, 0xd5, 0x88, 0xbe, 0x84, 0x0f,
- 0x99, 0x2a, 0x2c, 0xbc, 0xc3, 0x0c, 0x15, 0x7e, 0xc5, 0x04, 0x3a, 0x2a,
- 0x62, 0xfe, 0xfd, 0x93, 0x30, 0xc3, 0x07, 0x53, 0x9f, 0x17, 0xcd, 0xef,
- 0xfc, 0x39, 0xa9, 0x71, 0x24, 0xe2, 0x75, 0xff, 0xfe, 0x51, 0x88, 0xea,
- 0x93, 0x6b, 0x1a, 0x21, 0x8d, 0x60, 0x9d, 0x58, 0x89, 0xd4, 0x3b, 0xbe,
- 0x62, 0x05, 0xa7, 0x5f, 0xf7, 0xdf, 0x7f, 0x63, 0x9c, 0x43, 0xad, 0xc3,
- 0xab, 0x0f, 0x26, 0x47, 0x37, 0x98, 0x61, 0x82, 0xaf, 0xe4, 0x85, 0x38,
- 0x9f, 0x2a, 0x62, 0xfe, 0xfa, 0x38, 0xe0, 0x3a, 0xfd, 0x9e, 0xe6, 0x32,
- 0x75, 0xb5, 0xe1, 0x18, 0x7d, 0x40, 0xe1, 0xe0, 0x90, 0x5c, 0x16, 0x81,
- 0x37, 0x1c, 0x8c, 0xb6, 0xfd, 0x3f, 0x71, 0xf6, 0x09, 0xd6, 0x4e, 0x27,
- 0xe8, 0x31, 0xc9, 0x04, 0xd6, 0xfa, 0x3a, 0x9c, 0x3a, 0xff, 0x38, 0xb4,
- 0x51, 0xf7, 0x3a, 0x9d, 0x94, 0xc2, 0xd2, 0x4c, 0x8d, 0x55, 0x48, 0x41,
- 0xc8, 0xdd, 0x0e, 0x7b, 0x0e, 0xee, 0x47, 0xb7, 0x06, 0x9e, 0x91, 0x8c,
- 0x36, 0xb5, 0x0b, 0xef, 0xca, 0xb2, 0x9e, 0x3b, 0x54, 0x41, 0x72, 0xb2,
- 0x87, 0x5f, 0xf9, 0xd9, 0xfa, 0xad, 0x3b, 0x21, 0xe9, 0xd7, 0xf3, 0xaf,
- 0xbd, 0x8f, 0x9d, 0x7f, 0xfa, 0x4c, 0xc4, 0xb8, 0xed, 0xf8, 0xe2, 0xce,
- 0xbf, 0xfe, 0x45, 0xee, 0xdd, 0x78, 0xc1, 0x1c, 0x4f, 0x4e, 0xbc, 0x9c,
- 0x09, 0xd4, 0xad, 0x26, 0x78, 0xd1, 0xae, 0x21, 0x41, 0x67, 0xd2, 0x67,
- 0x28, 0x5a, 0x69, 0xf6, 0x31, 0x7d, 0x69, 0xf2, 0x30, 0x75, 0x6c, 0xb4,
- 0xad, 0xf0, 0xd4, 0x56, 0x25, 0x0f, 0x48, 0xfb, 0xda, 0x5f, 0x83, 0x67,
- 0x62, 0x41, 0x3d, 0x4d, 0x96, 0xb5, 0x6d, 0x49, 0x4f, 0x12, 0x9f, 0x56,
- 0xde, 0x7a, 0x49, 0x27, 0xa6, 0x19, 0xa5, 0x0a, 0xf6, 0x95, 0x36, 0xb9,
- 0xcd, 0xfe, 0x56, 0x34, 0x51, 0x5b, 0x9c, 0xfb, 0x3d, 0xd5, 0x3f, 0x43,
- 0x14, 0x69, 0xe5, 0x7a, 0xb4, 0xfd, 0x5f, 0xae, 0x9d, 0xc3, 0x2f, 0xf2,
- 0x74, 0x78, 0x6c, 0x47, 0x0f, 0x3d, 0x3c, 0xcb, 0xe6, 0x98, 0x52, 0xaa,
- 0x51, 0xad, 0x4d, 0x18, 0xd9, 0xab, 0x73, 0x18, 0x91, 0xbf, 0x4d, 0xea,
- 0xf3, 0xe7, 0x5f, 0xe9, 0xb3, 0xb2, 0x88, 0x91, 0xa2, 0xe3, 0xbf, 0xd3,
- 0x67, 0x65, 0x11, 0x23, 0x45, 0xd7, 0x7f, 0xf4, 0xd0, 0xd9, 0xb3, 0xb2,
- 0x88, 0x91, 0xa2, 0x51, 0xa7, 0x8c, 0x7f, 0x25, 0xb0, 0x86, 0x01, 0x72,
- 0x90, 0x8f, 0x91, 0x42, 0x46, 0x80, 0xae, 0xbf, 0x19, 0x8d, 0xc6, 0x7a,
- 0x77, 0xa2, 0x9f, 0x9f, 0xaa, 0x3f, 0xbf, 0xfd, 0x32, 0xe1, 0xb3, 0x67,
- 0x65, 0x11, 0x23, 0x44, 0xb5, 0x7e, 0xec, 0xa2, 0x24, 0x68, 0x8d, 0xef,
- 0xfd, 0x0d, 0x9b, 0x3b, 0x28, 0x89, 0x1a, 0x25, 0xfb, 0xf9, 0xff, 0xe7,
- 0x91, 0xf3, 0xad, 0x36, 0x22, 0xad, 0x66, 0x7c, 0x4a, 0xbf, 0xd3, 0x67,
- 0x65, 0x11, 0x23, 0x45, 0x57, 0x72, 0x2a, 0x3a, 0xf9, 0x17, 0x13, 0x8e,
- 0xa5, 0x0d, 0xcf, 0xc5, 0xef, 0x0a, 0xa6, 0x0e, 0xbf, 0xa3, 0x8c, 0x8b,
- 0x80, 0xeb, 0xff, 0xbf, 0xc7, 0xd0, 0xc0, 0x67, 0xe4, 0xe9, 0xd7, 0x9d,
- 0xb8, 0x75, 0x01, 0x11, 0xbb, 0x96, 0x32, 0x8f, 0x7f, 0xca, 0x60, 0xe6,
- 0xff, 0x85, 0x9d, 0x70, 0x10, 0xeb, 0xfb, 0x3b, 0x28, 0x89, 0x1a, 0x24,
- 0x0a, 0xf0, 0x79, 0xb3, 0x0a, 0xdf, 0xb5, 0x03, 0x1b, 0x9d, 0x4d, 0x3c,
- 0xbd, 0xc9, 0x6f, 0xf3, 0x5f, 0xbb, 0x3f, 0x76, 0x3a, 0xff, 0x77, 0x65,
- 0xb8, 0xb7, 0x47, 0x53, 0x9f, 0x3e, 0x1a, 0x5f, 0xfe, 0xc6, 0x79, 0x0b,
- 0xff, 0x1f, 0xe1, 0x59, 0xd5, 0xb2, 0xac, 0x30, 0x11, 0x64, 0x2a, 0xd4,
- 0x32, 0x88, 0x68, 0x0c, 0x22, 0xbc, 0x90, 0x5f, 0xfc, 0x39, 0xb4, 0xd3,
- 0xce, 0x23, 0x9f, 0x3a, 0xa6, 0x45, 0xdf, 0x5d, 0xaf, 0xf4, 0xd9, 0xd9,
- 0x44, 0x48, 0xd1, 0x64, 0x5f, 0xe9, 0xb3, 0xb2, 0x88, 0x91, 0xa2, 0xd7,
- 0xbf, 0xfd, 0x9e, 0x5f, 0x69, 0xb1, 0x9f, 0x81, 0xc4, 0xeb, 0xfd, 0x36,
- 0x76, 0x51, 0x12, 0x34, 0x5c, 0x97, 0xee, 0xca, 0x22, 0x46, 0x8b, 0xb2,
- 0xff, 0xd0, 0xd9, 0xb3, 0xb2, 0x88, 0x91, 0xa2, 0x8e, 0xb4, 0xd8, 0x7f,
- 0xab, 0x33, 0xbe, 0x17, 0x6a, 0xce, 0xb3, 0x4e, 0xbf, 0x76, 0x51, 0x12,
- 0x34, 0x52, 0xb7, 0xfd, 0x2e, 0x23, 0x3c, 0x7d, 0xb0, 0xeb, 0xff, 0xdc,
- 0x7d, 0x9f, 0x89, 0x3a, 0x01, 0xc4, 0x3a, 0x63, 0x73, 0x73, 0x66, 0xc4,
- 0x63, 0xb2, 0xd9, 0x5b, 0xa6, 0x0f, 0x10, 0xd7, 0xb4, 0xc0, 0x4d, 0x41,
- 0x71, 0x93, 0xd6, 0xcc, 0x88, 0x16, 0xc6, 0x05, 0xb9, 0xb2, 0x4b, 0xf6,
- 0x59, 0x27, 0xa7, 0xe2, 0x7f, 0xa4, 0xcf, 0xc2, 0xf2, 0x74, 0x6f, 0x17,
- 0xfc, 0xd9, 0xb3, 0xb2, 0x88, 0x91, 0xa2, 0x38, 0xbf, 0xe4, 0x9b, 0x3b,
- 0x28, 0x89, 0x1a, 0x2b, 0x5b, 0x4d, 0x08, 0x89, 0xfa, 0x2d, 0xff, 0xe9,
- 0x97, 0x0d, 0x9b, 0x3b, 0x28, 0x89, 0x1a, 0x25, 0xbb, 0xb3, 0x73, 0xaf,
- 0xf0, 0x31, 0x6b, 0x74, 0xd1, 0xd5, 0xb9, 0xe3, 0xa0, 0xb5, 0xee, 0x01,
- 0xa7, 0x5f, 0xf6, 0x6e, 0x39, 0xef, 0xb0, 0xd3, 0xae, 0x5c, 0x8e, 0xa7,
- 0x3c, 0xf6, 0x9c, 0xdf, 0xff, 0xdc, 0x8d, 0xfd, 0x07, 0x21, 0xb9, 0xa1,
- 0x0c, 0x79, 0x3a, 0xfe, 0x4e, 0x8a, 0x7f, 0x47, 0x5f, 0xbb, 0x03, 0x8e,
- 0x75, 0x1a, 0x21, 0xbe, 0x1e, 0x7c, 0x15, 0xdf, 0xe6, 0xa0, 0x83, 0x10,
- 0x07, 0x5f, 0x63, 0x2d, 0xc3, 0xaf, 0xfd, 0x0d, 0x9b, 0x3b, 0x28, 0x89,
- 0x1a, 0x26, 0x0b, 0xf7, 0xba, 0x81, 0xf4, 0xeb, 0xff, 0xbf, 0x3c, 0xfb,
- 0x7c, 0x5c, 0x3f, 0xd1, 0xd7, 0xdb, 0xc9, 0x14, 0x3a, 0xb0, 0xfa, 0xbe,
- 0x8f, 0x7f, 0xb4, 0x9c, 0x45, 0xe2, 0x87, 0x5f, 0xfe, 0x8d, 0xb8, 0x8e,
- 0x38, 0xca, 0x75, 0x0e, 0xaf, 0x9f, 0xcb, 0x06, 0x57, 0x4b, 0x0e, 0xb8,
- 0x3e, 0x95, 0x48, 0x6b, 0x3a, 0x2b, 0x7f, 0xb0, 0x03, 0x9f, 0xe6, 0x1d,
- 0x7f, 0x6d, 0xe6, 0x7a, 0x07, 0xd3, 0xaf, 0xec, 0xff, 0xdf, 0xba, 0x3a,
- 0xfe, 0x81, 0xf7, 0x6f, 0x7e, 0x75, 0x3a, 0x23, 0x84, 0xce, 0x78, 0xb2,
- 0xd3, 0x3a, 0xe5, 0x9e, 0xc4, 0x40, 0x6b, 0xc2, 0x19, 0x42, 0xb3, 0x73,
- 0x4e, 0x98, 0x2c, 0x86, 0x12, 0x86, 0x12, 0x5a, 0x84, 0xd7, 0xd3, 0xe7,
- 0x10, 0x79, 0x85, 0xf5, 0xe5, 0x87, 0xa5, 0x5f, 0xfa, 0x1b, 0x36, 0x76,
- 0x51, 0x12, 0x34, 0x4c, 0x77, 0xcf, 0xd7, 0x54, 0x75, 0xa6, 0x44, 0x44,
- 0x2c, 0x73, 0x89, 0x57, 0xe4, 0x7d, 0x9f, 0xa7, 0x5d, 0x1a, 0x3a, 0xfb,
- 0xc7, 0xf3, 0x87, 0x59, 0xf8, 0x6e, 0x34, 0x2b, 0x79, 0xc7, 0x63, 0xaf,
- 0xff, 0xff, 0x9b, 0xae, 0x60, 0x58, 0xd7, 0x32, 0x59, 0xaf, 0x19, 0xbb,
- 0x74, 0x82, 0x87, 0x5f, 0x4a, 0x22, 0x46, 0x8a, 0xc6, 0xff, 0xd3, 0xd9,
- 0xf1, 0xc0, 0xb8, 0xfc, 0xea, 0x51, 0x32, 0xb9, 0x13, 0x6e, 0x37, 0xd7,
- 0xff, 0x96, 0xdf, 0xfe, 0x71, 0xfa, 0x81, 0x71, 0xc9, 0x3f, 0x4e, 0xbf,
- 0xb3, 0x5b, 0xb5, 0xf8, 0x75, 0xcf, 0x38, 0xeb, 0x03, 0x87, 0x88, 0x25,
- 0xb7, 0xfc, 0xfb, 0xb5, 0x96, 0xc7, 0x76, 0x3a, 0xb0, 0xf8, 0x90, 0x9e,
- 0xff, 0xd8, 0x0e, 0xa0, 0x76, 0xf7, 0x4d, 0x3a, 0xf9, 0x71, 0xbf, 0xce,
- 0xbf, 0xfb, 0x67, 0xff, 0x8f, 0x32, 0xf2, 0xab, 0xce, 0x8e, 0xbf, 0xee,
- 0xbe, 0xa3, 0xa2, 0xed, 0x3a, 0xba, 0x88, 0x69, 0xca, 0x17, 0x9b, 0x1b,
- 0x1d, 0x70, 0x3e, 0x75, 0x4f, 0xe8, 0xff, 0xc8, 0x54, 0x6e, 0x4a, 0x23,
- 0x97, 0xfe, 0x18, 0x07, 0x1e, 0x77, 0x20, 0x4e, 0xbf, 0xff, 0xf0, 0x76,
- 0xc9, 0x78, 0x10, 0xaa, 0xf1, 0x9b, 0xb7, 0x02, 0x3e, 0xe8, 0xeb, 0xfe,
- 0x8d, 0xc7, 0x01, 0xc8, 0x60, 0xea, 0x02, 0x3a, 0x44, 0xf7, 0x4e, 0x97,
- 0xf6, 0xcc, 0xb6, 0x7f, 0xee, 0xc7, 0x5f, 0x08, 0xe7, 0xce, 0xa5, 0x68,
- 0xf5, 0x5c, 0xda, 0xfe, 0xdb, 0xcc, 0xf4, 0x0f, 0xa7, 0x5f, 0xfc, 0xcf,
- 0x21, 0x7f, 0xe3, 0xfc, 0x2b, 0x3a, 0x9c, 0xfe, 0x30, 0xce, 0xf7, 0x12,
- 0x67, 0x5e, 0x93, 0xc8, 0xe2, 0x64, 0x9b, 0xc8, 0x76, 0x89, 0x06, 0xa3,
- 0x3f, 0xfc, 0x65, 0xf3, 0xd0, 0x84, 0xf3, 0x09, 0xeb, 0xfb, 0xbd, 0x70,
- 0x62, 0xce, 0xbb, 0xcf, 0xa7, 0x5e, 0xe2, 0x2c, 0xeb, 0x32, 0x75, 0x41,
- 0xac, 0x08, 0xdd, 0xfa, 0x07, 0x60, 0xe8, 0xeb, 0xfe, 0x70, 0x73, 0x01,
- 0xd8, 0x91, 0xd4, 0x88, 0xef, 0xf4, 0xb0, 0x51, 0x74, 0x41, 0xf2, 0x7b,
- 0xda, 0xf3, 0xa3, 0xaf, 0xb7, 0xd9, 0xd4, 0x3a, 0x80, 0x78, 0x41, 0x1e,
- 0xbb, 0xee, 0x75, 0xf9, 0x78, 0x2e, 0xd3, 0xaf, 0x83, 0xfc, 0xd1, 0xd7,
- 0xcf, 0xd8, 0x13, 0xaf, 0xb5, 0xa7, 0xf4, 0xea, 0x74, 0x43, 0xa1, 0x2f,
- 0x08, 0x58, 0x1f, 0xbf, 0x3b, 0x7d, 0x0b, 0x4e, 0xbf, 0xe4, 0x97, 0x31,
- 0x91, 0x70, 0x1d, 0x7c, 0xdf, 0xe7, 0x93, 0xaf, 0x75, 0xd6, 0x75, 0x41,
- 0xbe, 0x60, 0x8e, 0xfc, 0xfb, 0x79, 0xc6, 0x4e, 0xbc, 0xe2, 0xd3, 0xa9,
- 0x94, 0xc0, 0xb8, 0x50, 0x2e, 0xba, 0x21, 0xf9, 0x55, 0xff, 0x9f, 0x35,
- 0xe1, 0xd0, 0x1e, 0x5a, 0x75, 0xfc, 0x8c, 0x6b, 0x6c, 0x60, 0xea, 0x13,
- 0xef, 0xfa, 0x05, 0xf9, 0xc1, 0xfc, 0x91, 0xd4, 0xd3, 0xc7, 0xd1, 0x0d,
- 0xf4, 0x0c, 0x32, 0x75, 0xde, 0x56, 0x75, 0xff, 0x07, 0xc7, 0xc6, 0x3d,
- 0xc1, 0x3a, 0xb6, 0x3f, 0x1e, 0x10, 0x08, 0xc5, 0xca, 0xa7, 0x1d, 0x7f,
- 0x3a, 0xf0, 0x51, 0x43, 0xad, 0xa3, 0xa9, 0x0d, 0xdc, 0x15, 0xdd, 0xeb,
- 0x95, 0x73, 0x0c, 0x15, 0x48, 0x6b, 0x98, 0x16, 0xbf, 0xd0, 0xd1, 0xcf,
- 0xf1, 0x0a, 0x98, 0xd0, 0xde, 0x8d, 0xf4, 0x75, 0xf7, 0x9e, 0x47, 0xce,
- 0xa0, 0x1b, 0xff, 0x8e, 0x5e, 0x71, 0x64, 0xeb, 0x85, 0xce, 0xb3, 0x27,
- 0x53, 0x27, 0x81, 0xd1, 0xb8, 0x14, 0xbf, 0xf9, 0x44, 0x19, 0x69, 0xd7,
- 0x1b, 0xfc, 0xeb, 0xde, 0xe2, 0xa3, 0xa9, 0x43, 0xe2, 0xea, 0x25, 0xf2,
- 0xf4, 0x15, 0x9d, 0x65, 0x0e, 0xbb, 0xaa, 0x1d, 0x4e, 0x79, 0x48, 0x45,
- 0xe4, 0x46, 0xff, 0xfb, 0x98, 0xdd, 0x3f, 0xdb, 0x8a, 0xf0, 0x3e, 0x9d,
- 0x7f, 0xf3, 0xb5, 0x3f, 0xcc, 0xdf, 0xe1, 0x73, 0xab, 0x48, 0x94, 0xfa,
- 0x8d, 0xb0, 0xea, 0x43, 0x65, 0x3c, 0x47, 0x4e, 0xa9, 0xdf, 0x18, 0x52,
- 0x12, 0x3c, 0x6d, 0x88, 0x7a, 0xd1, 0xd6, 0x59, 0xd5, 0xf2, 0xea, 0x70,
- 0x55, 0xd0, 0xa1, 0xd5, 0xc3, 0x70, 0x24, 0x57, 0x7d, 0xce, 0xbf, 0x3f,
- 0x32, 0x74, 0x1d, 0x50, 0x6f, 0x3d, 0x15, 0xbf, 0x93, 0xf9, 0xc8, 0x50,
- 0xeb, 0xfb, 0x81, 0x8d, 0xb8, 0x87, 0x5e, 0x61, 0x86, 0x0a, 0xbf, 0xe0,
- 0x3e, 0xde, 0x73, 0x91, 0xb9, 0x53, 0x17, 0xf4, 0x04, 0x4b, 0xc9, 0x32,
- 0xf3, 0xad, 0x0e, 0xac, 0x37, 0xb2, 0x23, 0xbe, 0x4e, 0xaa, 0x01, 0xd7,
- 0xee, 0x3e, 0xf0, 0xae, 0x75, 0xff, 0xf3, 0xff, 0x40, 0xcf, 0xa7, 0x03,
- 0x9b, 0xfc, 0xea, 0xe1, 0xfc, 0xfc, 0xaa, 0xdd, 0x3a, 0xe0, 0xe8, 0xeb,
- 0xff, 0xf6, 0x01, 0xf3, 0x7f, 0x3f, 0x41, 0x0b, 0x73, 0x47, 0x5e, 0x88,
- 0x13, 0xaf, 0xcb, 0x4f, 0xfb, 0x07, 0x56, 0xc9, 0xbc, 0xe4, 0x27, 0x15,
- 0xc8, 0xa0, 0x40, 0x45, 0xbe, 0xaa, 0x11, 0x9b, 0xee, 0x7d, 0x36, 0x3a,
- 0xff, 0x49, 0x34, 0x39, 0x3a, 0x0e, 0xbe, 0x7d, 0xa1, 0xa7, 0x5d, 0x9f,
- 0x3a, 0xfd, 0x9b, 0x0e, 0x6e, 0x75, 0x62, 0x2c, 0x77, 0x22, 0xe9, 0x97,
- 0x08, 0x44, 0x56, 0xf7, 0x1c, 0x07, 0x51, 0xd7, 0xdf, 0x5a, 0xfa, 0x75,
- 0xff, 0xde, 0xb8, 0xca, 0x3f, 0xef, 0x91, 0x69, 0xd7, 0x9a, 0x9c, 0x3a,
- 0xfb, 0xe3, 0x8d, 0x3a, 0xfd, 0x81, 0x9f, 0xb5, 0x07, 0x5f, 0xfe, 0x4d,
- 0x73, 0x00, 0x39, 0x38, 0x73, 0x47, 0x52, 0x89, 0x8b, 0x6e, 0x44, 0xca,
- 0x37, 0x46, 0xc4, 0x83, 0xe5, 0x74, 0xec, 0xeb, 0x8d, 0xa1, 0x16, 0xd2,
- 0x20, 0x42, 0x73, 0x23, 0x3e, 0xde, 0x30, 0x14, 0x84, 0x9b, 0x25, 0xfd,
- 0x55, 0x5b, 0x77, 0x25, 0x7b, 0xc4, 0x29, 0x3d, 0x5c, 0x9f, 0x88, 0x46,
- 0x30, 0x0d, 0x47, 0x33, 0xf8, 0xc7, 0x18, 0x49, 0x9e, 0x1b, 0xf3, 0x19,
- 0x05, 0xff, 0x4d, 0xf4, 0xc5, 0x5a, 0x0b, 0x9d, 0x7f, 0xff, 0xc1, 0x79,
- 0xbf, 0xa4, 0xe4, 0x27, 0xf3, 0xbe, 0xae, 0x1a, 0x75, 0x4c, 0x9f, 0xd6,
- 0xd1, 0xad, 0x00, 0xea, 0xfd, 0xd9, 0x44, 0x48, 0xd1, 0x5b, 0xdf, 0xfa,
- 0x1b, 0x36, 0x76, 0x51, 0x12, 0x34, 0x4e, 0x16, 0x9b, 0x0f, 0xf5, 0x66,
- 0x77, 0x4f, 0xe0, 0x3a, 0xe0, 0xf0, 0xeb, 0xf7, 0x65, 0x11, 0x23, 0x45,
- 0xa3, 0x7d, 0x28, 0x1f, 0x4e, 0xbf, 0xe6, 0x71, 0x5f, 0x5d, 0xec, 0x7c,
- 0xeb, 0xf9, 0xe0, 0x42, 0x0c, 0x3a, 0xe4, 0x50, 0xeb, 0xff, 0xf6, 0xcf,
- 0xf7, 0x07, 0x5f, 0x91, 0xa1, 0xcf, 0x4e, 0xbf, 0xf3, 0xef, 0x0a, 0xfc,
- 0x18, 0x57, 0xd8, 0xeb, 0xff, 0x3f, 0x7d, 0xc4, 0xce, 0xfc, 0x27, 0x53,
- 0xa3, 0x57, 0x8a, 0x9a, 0x44, 0xb6, 0x32, 0x98, 0xd6, 0xa1, 0xd7, 0x7f,
- 0xb9, 0xc0, 0xa8, 0xb7, 0xd1, 0xd7, 0xff, 0xe4, 0xd0, 0xe4, 0xe8, 0xf8,
- 0xe6, 0xb9, 0x0c, 0x9d, 0x58, 0x88, 0x86, 0x4d, 0x2f, 0xb3, 0xd8, 0xe1,
- 0xd7, 0x73, 0x47, 0x5a, 0x69, 0xf5, 0x58, 0xb4, 0xf8, 0x37, 0x82, 0xd2,
- 0x33, 0x64, 0x85, 0x67, 0x9c, 0x8d, 0x13, 0xf0, 0xb7, 0x9e, 0x23, 0xf2,
- 0x43, 0x7d, 0x28, 0x89, 0x1a, 0x2d, 0xab, 0xfb, 0x8e, 0xb7, 0x40, 0x1d,
- 0x5d, 0x3d, 0x8f, 0x96, 0xdf, 0xfb, 0x88, 0x08, 0x68, 0x38, 0x8b, 0x3a,
- 0xf9, 0xe7, 0x62, 0x1d, 0x7f, 0xce, 0xd7, 0xee, 0xcf, 0xdd, 0x8e, 0xbf,
- 0xe7, 0xef, 0x8d, 0x3f, 0x21, 0x0e, 0xbf, 0xdc, 0x48, 0x6f, 0xd3, 0x63,
- 0xab, 0x13, 0x23, 0x91, 0x17, 0x4f, 0x44, 0x85, 0x83, 0x99, 0xe3, 0x8b,
- 0xf9, 0x48, 0xe8, 0x02, 0x27, 0x5f, 0x93, 0x65, 0xbc, 0x8e, 0xbf, 0x46,
- 0xed, 0xf3, 0xa3, 0xad, 0x32, 0x87, 0xfd, 0xf2, 0xd9, 0xc4, 0xf5, 0x32,
- 0x62, 0x3e, 0xc3, 0x62, 0xe5, 0xf0, 0xeb, 0xf7, 0x65, 0x11, 0x23, 0x45,
- 0xcb, 0x69, 0x80, 0x79, 0x38, 0x2d, 0x7f, 0xa6, 0xce, 0xca, 0x22, 0x46,
- 0x8b, 0xb6, 0x9d, 0xd4, 0x05, 0x6c, 0x52, 0xd9, 0xd5, 0x10, 0x46, 0xce,
- 0xa4, 0xf6, 0x4a, 0x56, 0x4a, 0xea, 0xf0, 0xb6, 0xe4, 0xb3, 0xe1, 0x96,
- 0x75, 0xa7, 0x4f, 0x94, 0x5f, 0xe9, 0xb3, 0xb2, 0x88, 0x91, 0xa2, 0xa7,
- 0xb7, 0xce, 0xbf, 0xe7, 0x8d, 0xbc, 0x6f, 0xa7, 0x01, 0xd4, 0x87, 0x96,
- 0x22, 0x17, 0xd2, 0x88, 0x91, 0xa2, 0xb9, 0xbf, 0xd3, 0x67, 0x65, 0x11,
- 0x23, 0x45, 0x9d, 0x5d, 0x3e, 0xce, 0x16, 0xdf, 0xfe, 0xfb, 0xeb, 0xc0,
- 0x75, 0xf7, 0x65, 0x94, 0x3a, 0xff, 0x3f, 0x3c, 0x2e, 0x7c, 0x9f, 0x7e,
- 0x75, 0x62, 0x23, 0x27, 0x26, 0xdf, 0xbb, 0x9f, 0x45, 0x9d, 0x7d, 0x02,
- 0xe0, 0x3a, 0xfe, 0xc6, 0x5d, 0x6f, 0xe4, 0xeb, 0xf7, 0x65, 0x11, 0x23,
- 0x44, 0x85, 0x7f, 0xec, 0x5e, 0x47, 0x76, 0xf1, 0xba, 0xce, 0xbf, 0xe4,
- 0xdf, 0x5f, 0x17, 0x5e, 0x8e, 0xb9, 0xb3, 0x62, 0x2b, 0x38, 0x67, 0xea,
- 0x0d, 0xf4, 0xf9, 0xc7, 0x59, 0xd7, 0xfb, 0x39, 0xad, 0x67, 0x76, 0x3a,
- 0xd3, 0x01, 0x58, 0x9e, 0x42, 0x31, 0x21, 0x5d, 0xd2, 0x45, 0x93, 0x70,
- 0x7e, 0x21, 0xb5, 0xa3, 0xdf, 0x93, 0x5f, 0xfd, 0x37, 0x23, 0x43, 0x9f,
- 0xfb, 0xfa, 0x75, 0xff, 0xe9, 0x97, 0x0d, 0x9b, 0x3b, 0x28, 0x89, 0x1a,
- 0x27, 0xca, 0x92, 0xe6, 0x5a, 0xbc, 0xb9, 0xd5, 0xc2, 0x4f, 0x88, 0x97,
- 0x9a, 0x9b, 0x9d, 0x7e, 0xce, 0xe6, 0x32, 0x75, 0xa6, 0xe1, 0xe1, 0x79,
- 0x1c, 0xbf, 0x76, 0x51, 0x12, 0x34, 0x56, 0x57, 0xfe, 0x86, 0xcd, 0x9d,
- 0x94, 0x44, 0x8d, 0x13, 0x75, 0xa6, 0xc3, 0xfd, 0x59, 0x9d, 0x49, 0x1a,
- 0x09, 0x0a, 0x8b, 0xf7, 0x65, 0x11, 0x23, 0x44, 0xad, 0x7e, 0x17, 0x04,
- 0x70, 0xeb, 0xf4, 0xcb, 0x86, 0xcd, 0x87, 0xb0, 0x86, 0x77, 0xfe, 0x4d,
- 0x05, 0x62, 0x93, 0x83, 0x07, 0x5f, 0xce, 0x31, 0x28, 0x57, 0x3a, 0x9a,
- 0x7d, 0x6b, 0x3e, 0xbf, 0x76, 0x51, 0x12, 0x34, 0x4b, 0x97, 0xfc, 0x90,
- 0xdf, 0x8b, 0xaf, 0x47, 0x5f, 0x4e, 0x41, 0x73, 0xaf, 0xff, 0xd1, 0xf4,
- 0x0b, 0x45, 0x1a, 0xff, 0x10, 0xb4, 0xeb, 0xff, 0xc8, 0x29, 0xee, 0xba,
- 0xe8, 0xd8, 0xd1, 0xd7, 0xe9, 0x97, 0x0d, 0x99, 0xd3, 0x45, 0xc2, 0x2e,
- 0x19, 0xc1, 0xb6, 0x88, 0x7e, 0xa5, 0x7f, 0xf4, 0xd0, 0xd9, 0xb3, 0xb2,
- 0x88, 0x91, 0xa2, 0x3b, 0xbf, 0xef, 0xf3, 0x1b, 0x34, 0x0e, 0x8e, 0xbf,
- 0xa7, 0xf1, 0x79, 0x60, 0x9d, 0x70, 0x78, 0x75, 0xfd, 0x3e, 0x8e, 0x72,
- 0x3e, 0x75, 0xfe, 0xc6, 0x34, 0xe3, 0xfd, 0x1d, 0x7f, 0xe7, 0x10, 0xfd,
- 0x22, 0x74, 0x34, 0xeb, 0xe9, 0x44, 0x48, 0xd1, 0x50, 0xd4, 0x8f, 0xab,
- 0xa7, 0xb7, 0x37, 0x0e, 0xbf, 0xe6, 0xfd, 0x3b, 0x12, 0x41, 0x3a, 0xff,
- 0xf9, 0xe1, 0x79, 0xd1, 0xc4, 0x9c, 0x9d, 0x83, 0xaf, 0xf9, 0xda, 0xfd,
- 0xd9, 0xfb, 0xb1, 0xd7, 0xf4, 0xe8, 0x5f, 0x18, 0x83, 0xaf, 0xff, 0xf2,
- 0x3f, 0xe3, 0x93, 0x6b, 0x98, 0x3f, 0xf1, 0xeb, 0x74, 0x75, 0xb1, 0x11,
- 0x24, 0x25, 0xf7, 0xdc, 0xfe, 0x6c, 0x75, 0xfb, 0x36, 0x81, 0x9c, 0x75,
- 0xff, 0xff, 0xfe, 0x76, 0xf8, 0xff, 0x11, 0xf5, 0xe3, 0x03, 0x27, 0x9d,
- 0xe3, 0x3b, 0xdc, 0x9c, 0x18, 0xe1, 0xd7, 0xdc, 0x18, 0x54, 0x75, 0x62,
- 0x60, 0x42, 0x45, 0xa2, 0x8f, 0xc2, 0x5a, 0xff, 0xff, 0x83, 0x0a, 0xe9,
- 0xb7, 0x21, 0x3e, 0xfc, 0x4f, 0xeb, 0x00, 0x75, 0xa6, 0x9f, 0x57, 0x19,
- 0x67, 0xc2, 0xf9, 0xfc, 0x5b, 0x63, 0x0c, 0x84, 0xe4, 0x88, 0xb7, 0x15,
- 0xe9, 0xb0, 0xa6, 0x6a, 0x19, 0x7f, 0x8c, 0xa2, 0x79, 0x06, 0xfa, 0x51,
- 0x12, 0x34, 0x55, 0x17, 0xfb, 0xaf, 0x3b, 0x76, 0xe7, 0xce, 0xae, 0x9f,
- 0x10, 0x4b, 0x6f, 0xfd, 0x0d, 0x9b, 0x3b, 0x28, 0x89, 0x1a, 0x26, 0xbb,
- 0x4d, 0x87, 0xd8, 0xb2, 0x2b, 0xf7, 0x65, 0x11, 0x23, 0x45, 0x59, 0x7f,
- 0xce, 0xd7, 0xee, 0xcf, 0xdd, 0x8e, 0xb4, 0xd8, 0x7d, 0x82, 0x67, 0x7f,
- 0xe9, 0xb8, 0xfb, 0xfd, 0xf9, 0x0a, 0xe7, 0x5f, 0xfd, 0x34, 0x36, 0x6c,
- 0xec, 0xa2, 0x24, 0x68, 0x91, 0x2f, 0xdd, 0x94, 0x44, 0x8d, 0x16, 0x95,
- 0xff, 0xa1, 0xb3, 0x67, 0x65, 0x11, 0x23, 0x44, 0xfb, 0x69, 0xb0, 0xff,
- 0x56, 0x67, 0x7f, 0xfa, 0x65, 0xc3, 0x66, 0xce, 0xca, 0x22, 0x46, 0x8a,
- 0x12, 0xfd, 0xc4, 0xd9, 0xfa, 0x75, 0xfb, 0xb2, 0x88, 0x91, 0xa2, 0x8f,
- 0xbf, 0xe7, 0x6b, 0xf7, 0x67, 0xee, 0xc7, 0x5f, 0xf8, 0x5d, 0x97, 0x17,
- 0x67, 0x8e, 0x75, 0xff, 0xfd, 0x80, 0xe3, 0xf9, 0x9b, 0xe3, 0x1e, 0xeb,
- 0x4f, 0xe9, 0x57, 0xe9, 0x97, 0x0d, 0x99, 0xd3, 0x2d, 0xc2, 0x71, 0x33,
- 0xf9, 0xcc, 0xf1, 0xe5, 0x3b, 0x33, 0x47, 0x68, 0xfb, 0xda, 0xe9, 0x8a,
- 0x2a, 0x4e, 0x4e, 0xca, 0x39, 0xfd, 0xe1, 0x28, 0x84, 0xec, 0xa1, 0x72,
- 0x19, 0xde, 0x94, 0x7e, 0x38, 0x4b, 0xfd, 0x36, 0x76, 0x51, 0x12, 0x34,
- 0x44, 0x57, 0xf6, 0x76, 0x51, 0x12, 0x34, 0x45, 0x77, 0xfc, 0xaf, 0x36,
- 0x76, 0x51, 0x12, 0x34, 0x57, 0x15, 0x32, 0x20, 0x20, 0xe2, 0xff, 0xf7,
- 0xae, 0x32, 0x9a, 0x3f, 0xef, 0x91, 0x69, 0xd7, 0xd3, 0x6c, 0xca, 0xb9,
- 0xd6, 0x4d, 0xcf, 0xd7, 0xd4, 0xdb, 0xec, 0xe4, 0x7c, 0xeb, 0xfd, 0x89,
- 0xdf, 0x7d, 0x0e, 0x8e, 0xb4, 0xfa, 0x27, 0xa9, 0xa2, 0x0b, 0xff, 0xfb,
- 0xfa, 0x4e, 0x42, 0x35, 0x07, 0xe1, 0xe7, 0x70, 0xeb, 0xf7, 0x65, 0x11,
- 0x23, 0x45, 0x3d, 0x7f, 0x96, 0x80, 0x0c, 0x75, 0xa7, 0x5c, 0xb4, 0x3a,
- 0x9c, 0xf1, 0xe4, 0x65, 0x7f, 0xff, 0x77, 0xa1, 0xef, 0x5c, 0x71, 0x44,
- 0xe7, 0x33, 0xc9, 0xd7, 0xff, 0x23, 0x70, 0x7d, 0x75, 0xa7, 0x5a, 0x75,
- 0xfe, 0x6b, 0xf7, 0x67, 0xee, 0xc7, 0x5f, 0x78, 0x18, 0x69, 0xd7, 0xe8,
- 0xce, 0x22, 0xce, 0xad, 0x1e, 0x3c, 0xe2, 0x2a, 0x74, 0x4f, 0xe3, 0xdd,
- 0xff, 0x38, 0xcb, 0x27, 0x67, 0xf4, 0x75, 0x4f, 0xea, 0xad, 0x5c, 0xb3,
- 0x16, 0x24, 0xf4, 0x84, 0x30, 0xb8, 0x30, 0xe1, 0x9c, 0x43, 0x7f, 0xfa,
- 0x1b, 0x30, 0x06, 0x18, 0xd6, 0x9f, 0xd3, 0xaf, 0xff, 0x7c, 0x73, 0xd8,
- 0x1f, 0x66, 0x5a, 0x2c, 0xea, 0x99, 0x30, 0xf0, 0x3d, 0x22, 0x5d, 0xc0,
- 0xc3, 0xaf, 0xfe, 0x40, 0x76, 0x37, 0x9b, 0xbd, 0x7d, 0x8e, 0xa9, 0x8f,
- 0x6f, 0x82, 0xb7, 0x01, 0xce, 0xbf, 0xff, 0x71, 0xfb, 0x8d, 0x48, 0xfe,
- 0x01, 0x03, 0x23, 0xaf, 0xce, 0xdf, 0x42, 0xd3, 0xaf, 0xa5, 0x11, 0x23,
- 0x45, 0x67, 0x4c, 0x9e, 0xaf, 0x4a, 0x2f, 0xbe, 0x8b, 0xd1, 0xd7, 0xf6,
- 0xcb, 0x71, 0x6e, 0x8e, 0xbf, 0x67, 0xf5, 0xe7, 0x47, 0x5e, 0x7d, 0x90,
- 0xeb, 0xf7, 0xfd, 0xf2, 0x2d, 0x3a, 0xf0, 0x63, 0x47, 0x5f, 0xf6, 0x35,
- 0x02, 0xaf, 0x3e, 0x7a, 0xb3, 0xaf, 0xd8, 0xce, 0xc1, 0xf4, 0xeb, 0x4c,
- 0xea, 0x88, 0x40, 0x2b, 0x90, 0xa7, 0xdc, 0x8f, 0xa4, 0x2b, 0x2d, 0xe1,
- 0x4c, 0x0d, 0x89, 0x56, 0x86, 0xfc, 0xa0, 0xdf, 0xfb, 0x89, 0xf8, 0xee,
- 0xce, 0x80, 0x3a, 0xfd, 0xf4, 0x1c, 0x59, 0xd7, 0xcd, 0x81, 0x9b, 0x0f,
- 0x89, 0x51, 0xed, 0xff, 0xd3, 0x43, 0x66, 0xce, 0xca, 0x22, 0x46, 0x89,
- 0x16, 0xfe, 0xce, 0xca, 0x22, 0x46, 0x8b, 0x26, 0xff, 0xf7, 0xf5, 0xe7,
- 0x53, 0x66, 0xc8, 0x2d, 0xd1, 0xd5, 0x32, 0x21, 0x70, 0xe2, 0xfe, 0xce,
- 0xca, 0x22, 0x46, 0x8b, 0x62, 0xff, 0xfe, 0x9f, 0x79, 0xe0, 0x73, 0xbf,
- 0xd7, 0x19, 0xf1, 0xe3, 0x93, 0xc7, 0x5e, 0xe8, 0x78, 0x75, 0xdf, 0x99,
- 0xd1, 0x0f, 0xd6, 0xba, 0x99, 0x1d, 0xc9, 0x0b, 0xfb, 0xd9, 0xac, 0x3a,
- 0xfa, 0x51, 0x12, 0x34, 0x5b, 0x77, 0xda, 0xda, 0x3a, 0x75, 0x74, 0xf3,
- 0xfe, 0x5b, 0x7f, 0x27, 0x3e, 0x9e, 0x84, 0xeb, 0xfe, 0x76, 0xbf, 0x76,
- 0x7e, 0xec, 0x75, 0xa6, 0x6a, 0x3c, 0x71, 0xa5, 0x92, 0x21, 0x2d, 0xbd,
- 0x3f, 0xf0, 0x07, 0x5e, 0xdb, 0x88, 0x75, 0xff, 0xa7, 0xf9, 0xfd, 0x5b,
- 0x7f, 0x98, 0x2f, 0xe9, 0xd7, 0xf3, 0x8b, 0x40, 0x15, 0x9d, 0x7e, 0xec,
- 0xa2, 0x24, 0x68, 0xbc, 0x2f, 0xbf, 0x3d, 0x9c, 0x3a, 0xfc, 0xb7, 0x16,
- 0xc1, 0xd7, 0xfe, 0xf2, 0xbd, 0xdb, 0xfc, 0x1f, 0xe8, 0xeb, 0xb1, 0x43,
- 0xa9, 0xcf, 0x5f, 0x10, 0x6f, 0x93, 0x6c, 0x59, 0xd7, 0xec, 0x1f, 0x55,
- 0x39, 0xd7, 0xe7, 0xf2, 0x18, 0xd1, 0xd7, 0xff, 0x67, 0x39, 0x0d, 0x5a,
- 0x3f, 0x5a, 0x75, 0xcf, 0xe9, 0xd4, 0xd3, 0xd8, 0xfa, 0x15, 0x4f, 0xaa,
- 0xa5, 0x67, 0xf2, 0x15, 0x6f, 0x1c, 0xd9, 0x3b, 0x0b, 0x37, 0x33, 0x42,
- 0x4e, 0x3e, 0x41, 0x07, 0xa4, 0x22, 0x51, 0xf8, 0x40, 0x5f, 0xed, 0xe6,
- 0xcf, 0x63, 0xba, 0x3a, 0xa6, 0x47, 0x8b, 0xc2, 0xf2, 0xf2, 0x66, 0xe7,
- 0x5f, 0x4a, 0x22, 0x46, 0x8b, 0xd2, 0xff, 0xc9, 0xfe, 0x0c, 0x37, 0xd8,
- 0xf4, 0xea, 0xe9, 0xf5, 0xac, 0xb6, 0xf2, 0xd3, 0xe7, 0x5f, 0xf4, 0x7d,
- 0xae, 0xa7, 0xd3, 0x63, 0xa9, 0x67, 0xa8, 0x23, 0x77, 0xec, 0x5f, 0x20,
- 0x07, 0x5a, 0x60, 0x26, 0x87, 0x90, 0x86, 0xf2, 0xec, 0xa8, 0x86, 0x9d,
- 0xb2, 0x2a, 0xda, 0x17, 0xed, 0x84, 0xc6, 0x4e, 0x20, 0xca, 0x11, 0x89,
- 0x29, 0x11, 0x98, 0xc1, 0xfa, 0x74, 0xb8, 0x6b, 0x7b, 0x18, 0x88, 0xc6,
- 0x32, 0x19, 0x79, 0x2c, 0x46, 0xd7, 0x70, 0x78, 0x75, 0xff, 0xc1, 0x76,
- 0x47, 0x27, 0x42, 0xd6, 0x87, 0x5f, 0x67, 0x23, 0xe7, 0x5f, 0xec, 0x4e,
- 0xfb, 0xe8, 0x74, 0x75, 0xa7, 0xd5, 0x11, 0x30, 0x28, 0x9a, 0x20, 0xbf,
- 0x27, 0xdf, 0x7d, 0x8e, 0xbf, 0x76, 0x51, 0x12, 0x34, 0x44, 0x77, 0xff,
- 0xdc, 0x0e, 0xb5, 0x8b, 0x1c, 0x9d, 0xe1, 0xd5, 0x93, 0xaf, 0xfc, 0xd7,
- 0xdb, 0xb9, 0xff, 0xa7, 0xce, 0xbf, 0xec, 0xee, 0x6b, 0x20, 0x76, 0x3a,
- 0xff, 0xff, 0x72, 0x13, 0xef, 0xc1, 0xcf, 0xf1, 0x39, 0x88, 0xc1, 0xd7,
- 0xff, 0xff, 0xbf, 0xf4, 0x5f, 0x53, 0x37, 0x10, 0xfd, 0xf9, 0xe2, 0x72,
- 0x7d, 0x97, 0x3a, 0x9d, 0x1b, 0x18, 0xbb, 0x76, 0xcb, 0x2a, 0xe6, 0x18,
- 0x2a, 0xff, 0xd3, 0x4b, 0x88, 0xcf, 0x1f, 0x69, 0xbd, 0x35, 0xec, 0x0b,
- 0xdf, 0x4e, 0x7f, 0xb9, 0xd4, 0xd3, 0xfd, 0x45, 0xbb, 0xfb, 0x21, 0x79,
- 0xbf, 0xce, 0xb9, 0x5a, 0x57, 0x3a, 0xfe, 0x57, 0x1c, 0xe4, 0x7c, 0xeb,
- 0xf9, 0xd4, 0xc1, 0x45, 0x0e, 0xbf, 0xb3, 0xea, 0xbf, 0x9c, 0x3a, 0xb1,
- 0x11, 0x02, 0x5d, 0xa2, 0xcb, 0xff, 0xfa, 0x53, 0x76, 0x05, 0x3f, 0x37,
- 0x5f, 0xe3, 0x1e, 0x9d, 0x53, 0xe2, 0xe9, 0x84, 0xff, 0x0a, 0xe7, 0x3b,
- 0xc2, 0x89, 0x19, 0xee, 0xae, 0x87, 0xdd, 0x8c, 0x3a, 0x21, 0x9b, 0xe9,
- 0x0e, 0x8b, 0x3f, 0x0a, 0x69, 0xc5, 0xd7, 0x2a, 0xe1, 0xd7, 0xee, 0xca,
- 0x22, 0x46, 0x88, 0xba, 0xfd, 0xff, 0x7c, 0x8b, 0x4a, 0xb4, 0xdb, 0x1f,
- 0xae, 0x0c, 0x41, 0x9d, 0x4c, 0x9b, 0xf3, 0x63, 0x49, 0xbf, 0xf9, 0x70,
- 0xd9, 0xb3, 0xb2, 0x88, 0x91, 0xa2, 0x66, 0xbf, 0x95, 0x8a, 0xb6, 0x9f,
- 0x74, 0xff, 0x3a, 0xf6, 0xef, 0xa3, 0xaf, 0x49, 0x16, 0x75, 0xd3, 0xca,
- 0xd1, 0xd7, 0x60, 0x4e, 0xbf, 0xfd, 0xc7, 0x5c, 0x7f, 0x37, 0xf5, 0x7e,
- 0x78, 0x75, 0xfd, 0xfc, 0xdb, 0x3d, 0x64, 0xeb, 0xfd, 0xe3, 0x06, 0x3b,
- 0xec, 0xf1, 0xd7, 0xff, 0xe5, 0xc7, 0x33, 0x7f, 0x78, 0xc4, 0x71, 0x9e,
- 0x04, 0xea, 0x02, 0x24, 0x30, 0xde, 0xed, 0x61, 0xd7, 0xde, 0xba, 0xaf,
- 0x9d, 0x7f, 0xff, 0xe4, 0x17, 0x90, 0xba, 0xfc, 0x3f, 0x7a, 0x93, 0xbb,
- 0x11, 0xe9, 0xd4, 0xad, 0x2a, 0x06, 0x90, 0xf2, 0x0a, 0xb2, 0x9b, 0xc8,
- 0x5f, 0xc1, 0x17, 0xa2, 0xbf, 0x24, 0xbf, 0x98, 0x71, 0x1c, 0xf9, 0xd7,
- 0xd1, 0xc4, 0x64, 0xeb, 0xee, 0x32, 0xe0, 0x3a, 0xb0, 0xfb, 0xa4, 0x57,
- 0x04, 0x36, 0x91, 0xd7, 0xff, 0xef, 0x77, 0x6f, 0x02, 0xfd, 0x9b, 0x89,
- 0x28, 0xe9, 0xd7, 0xff, 0xfe, 0x45, 0xa7, 0x78, 0x1d, 0x35, 0xe7, 0x75,
- 0xc7, 0xfc, 0xc6, 0x9d, 0x7f, 0xe4, 0xfa, 0x49, 0x01, 0xfc, 0x91, 0xd5,
- 0xf4, 0x54, 0x2a, 0x6c, 0xbe, 0xfc, 0xf6, 0x70, 0xeb, 0xff, 0xfd, 0x03,
- 0x21, 0xc0, 0x70, 0x3e, 0x38, 0xed, 0xeb, 0xec, 0x75, 0x62, 0x21, 0x42,
- 0x49, 0x7f, 0xff, 0xa1, 0x41, 0xcf, 0x43, 0xaf, 0x0d, 0x4e, 0x3c, 0x86,
- 0x0e, 0xbe, 0xfa, 0x71, 0x0e, 0xbf, 0xe8, 0xeb, 0x7c, 0x64, 0x81, 0x87,
- 0x53, 0xaa, 0x86, 0xc8, 0xc0, 0x39, 0x0a, 0xa8, 0x22, 0x16, 0x10, 0x90,
- 0x5b, 0xa7, 0x5f, 0xdf, 0xc5, 0xef, 0x8b, 0x3a, 0xdc, 0xc3, 0x7a, 0x82,
- 0x17, 0xff, 0xe0, 0x20, 0xed, 0x9a, 0x48, 0xe4, 0xcc, 0x30, 0xc1, 0x57,
- 0xf7, 0xf8, 0xfb, 0x70, 0x27, 0x5f, 0xdb, 0xb7, 0x5e, 0x85, 0x93, 0xaf,
- 0xfb, 0x6c, 0xf4, 0x01, 0x8e, 0xb4, 0xeb, 0xd1, 0x12, 0x34, 0x59, 0xf7,
- 0xf7, 0xb0, 0x2d, 0x45, 0x9d, 0x5b, 0x22, 0x36, 0x47, 0x5e, 0x93, 0xdf,
- 0xf9, 0x38, 0xed, 0x4f, 0xbf, 0xf4, 0x75, 0xff, 0xf2, 0x77, 0x91, 0xe3,
- 0x27, 0x0e, 0x6b, 0x04, 0xeb, 0xcc, 0x30, 0xc1, 0x57, 0xfe, 0x86, 0xe8,
- 0x72, 0x40, 0xce, 0x95, 0x31, 0x7f, 0x7f, 0xc1, 0xff, 0x32, 0x77, 0x86,
- 0xac, 0xeb, 0xff, 0x6e, 0xd1, 0x0f, 0xbe, 0x24, 0xbf, 0x4e, 0xb9, 0xd4,
- 0x3a, 0x9c, 0xf6, 0xb6, 0x44, 0xbf, 0xdc, 0x40, 0x0c, 0x43, 0x27, 0x5f,
- 0xe0, 0x70, 0x31, 0xec, 0xf6, 0x1d, 0x4e, 0x7c, 0xe8, 0x63, 0x7f, 0xc8,
- 0x20, 0xf2, 0x00, 0xff, 0x47, 0x53, 0x57, 0x02, 0xe4, 0x4b, 0xba, 0xc3,
- 0x25, 0xdd, 0x85, 0xf2, 0xcc, 0xb8, 0x79, 0xeb, 0x70, 0xa6, 0x6a, 0x12,
- 0xff, 0x84, 0x4c, 0xe2, 0x0b, 0xfe, 0xec, 0x31, 0xc4, 0x7e, 0xb9, 0xd7,
- 0xfe, 0xea, 0x69, 0xbe, 0x78, 0xe2, 0xe7, 0x5f, 0x75, 0x1d, 0x67, 0x5f,
- 0xff, 0xbe, 0xa0, 0x5f, 0x01, 0xcc, 0xd6, 0xed, 0x7e, 0x1d, 0x5d, 0x45,
- 0xa2, 0xcf, 0x84, 0x82, 0xe8, 0x69, 0xd7, 0xff, 0xff, 0xf0, 0xc3, 0x1f,
- 0xce, 0x0e, 0x7c, 0x3e, 0xae, 0x1b, 0x00, 0x71, 0x8e, 0xc3, 0x4e, 0xbf,
- 0xd9, 0xce, 0x07, 0xf0, 0x27, 0x59, 0x00, 0x8c, 0xb6, 0x45, 0x7b, 0x08,
- 0x5b, 0xf7, 0x59, 0x9d, 0x80, 0x3a, 0xff, 0xd8, 0xc2, 0xae, 0xe2, 0xa1,
- 0x0b, 0x07, 0x53, 0xa7, 0x45, 0xc8, 0x7d, 0x41, 0xd8, 0x95, 0x5f, 0xff,
- 0xff, 0xb3, 0xdd, 0x66, 0x0a, 0x9e, 0x7a, 0x2f, 0x9c, 0x9b, 0x43, 0x9b,
- 0x2f, 0x16, 0x75, 0xfa, 0x74, 0x71, 0xfc, 0x9d, 0x58, 0x8a, 0xe4, 0x84,
- 0x25, 0xed, 0x3e, 0xc7, 0x5e, 0x9e, 0xce, 0x1d, 0x4d, 0x3e, 0x0d, 0x13,
- 0x7c, 0x72, 0xf7, 0x02, 0xc1, 0xd7, 0xbd, 0x0c, 0x8e, 0xbd, 0xfc, 0xf2,
- 0x75, 0xfc, 0xfb, 0xeb, 0xc7, 0x5c, 0xeb, 0xc0, 0x0c, 0x8e, 0xbe, 0x00,
- 0xbb, 0x4e, 0xa4, 0x37, 0x90, 0x39, 0x7c, 0xff, 0xd3, 0x9d, 0x40, 0x4c,
- 0x07, 0x71, 0xd4, 0x1d, 0x58, 0xef, 0x1a, 0xe7, 0x87, 0xee, 0xc9, 0x1d,
- 0x7f, 0x75, 0x27, 0x60, 0xe8, 0xeb, 0xf7, 0x05, 0xf3, 0xa6, 0x5f, 0xf9,
- 0x3a, 0xdc, 0xee, 0xc1, 0x80, 0x1a, 0x20, 0xd9, 0x8d, 0x2d, 0xfa, 0x24,
- 0x8b, 0x73, 0xaf, 0xe6, 0xf0, 0x63, 0x7f, 0x9d, 0x6c, 0x91, 0xe9, 0x09,
- 0x2d, 0xfe, 0x6a, 0x2d, 0xf9, 0xe4, 0x07, 0x5f, 0xfe, 0x7c, 0x1d, 0xff,
- 0x9d, 0x4d, 0xa1, 0x67, 0x5f, 0xa1, 0x8f, 0xe7, 0x34, 0x7f, 0x9f, 0x34,
- 0xa9, 0xf1, 0x3f, 0x67, 0x15, 0x6a, 0x96, 0x42, 0xb8, 0x61, 0x45, 0x7b,
- 0x58, 0xd3, 0xaf, 0xc9, 0xbb, 0x50, 0x4e, 0xbc, 0x9c, 0xc3, 0xae, 0x75,
- 0xe1, 0xe0, 0x48, 0x9a, 0xfd, 0x80, 0xd7, 0x1c, 0xea, 0x74, 0x56, 0xa2,
- 0xdf, 0x4b, 0x2f, 0x73, 0x04, 0xeb, 0xff, 0xe8, 0x53, 0xef, 0xdf, 0x7a,
- 0xff, 0x18, 0xf4, 0xeb, 0xff, 0xf8, 0x61, 0x4f, 0x1e, 0x46, 0x3f, 0xa4,
- 0xdf, 0x88, 0xc1, 0xd5, 0x88, 0xc9, 0x11, 0xa0, 0xa8, 0x5f, 0x20, 0xc0,
- 0x0e, 0xbf, 0xf2, 0xf3, 0xfa, 0xf3, 0xa8, 0x6e, 0x1d, 0x7e, 0xd3, 0xf7,
- 0xee, 0x74, 0xc6, 0xfe, 0x80, 0x89, 0x5d, 0x2f, 0x5f, 0xbc, 0xb3, 0x11,
- 0xd3, 0xaf, 0xb9, 0x89, 0x38, 0xeb, 0xfb, 0x49, 0xdc, 0x0f, 0x4e, 0xbf,
- 0xff, 0xce, 0xcf, 0x84, 0x90, 0x7b, 0xa0, 0xf8, 0x5a, 0x7f, 0x88, 0x75,
- 0x22, 0x3f, 0xd6, 0x47, 0xc2, 0x9f, 0x91, 0x2a, 0x2c, 0xb9, 0x73, 0xe9,
- 0xa2, 0xfc, 0xbf, 0xf9, 0xbf, 0x0b, 0x5a, 0xbf, 0xfd, 0xd6, 0x75, 0xfe,
- 0xfe, 0x9f, 0x6c, 0xd0, 0x0e, 0xbf, 0xfe, 0xe3, 0x83, 0x25, 0xe3, 0x07,
- 0x01, 0xc7, 0x3a, 0xff, 0xe4, 0xc1, 0xcc, 0xd7, 0x86, 0xe9, 0x67, 0x56,
- 0xe9, 0x84, 0xa2, 0x2b, 0x26, 0x7a, 0x4e, 0xbc, 0xa3, 0xf4, 0xeb, 0xf8,
- 0x0f, 0xef, 0x73, 0x73, 0xaa, 0x63, 0xca, 0x58, 0xe5, 0xfe, 0x75, 0xe2,
- 0x75, 0x96, 0x9d, 0x72, 0x32, 0x75, 0xff, 0xef, 0xbf, 0x06, 0x36, 0x7e,
- 0xf6, 0x1a, 0x75, 0xef, 0xa6, 0xc7, 0x5e, 0x17, 0x91, 0xd7, 0xff, 0x01,
- 0x19, 0xe3, 0xf7, 0x76, 0xbf, 0x4e, 0xbf, 0xfe, 0x17, 0x97, 0x8e, 0xe2,
- 0x06, 0x7e, 0xc5, 0x58, 0x75, 0x78, 0x4c, 0xb9, 0x05, 0x96, 0x90, 0x23,
- 0x9a, 0x1a, 0x54, 0x8b, 0x4e, 0xaf, 0x88, 0x09, 0x79, 0x19, 0x8a, 0x42,
- 0x27, 0x84, 0x71, 0x1b, 0x05, 0xff, 0x60, 0xb4, 0x71, 0x6f, 0x23, 0xaf,
- 0xdc, 0x49, 0xd8, 0x03, 0xaf, 0xd0, 0xb4, 0x55, 0x87, 0x5e, 0xfb, 0xee,
- 0x75, 0x61, 0xe1, 0xc1, 0x3d, 0xff, 0xff, 0x9f, 0x88, 0xb9, 0x99, 0x6c,
- 0x77, 0xcf, 0x13, 0x7d, 0x49, 0x36, 0x3a, 0x80, 0x99, 0x8a, 0x86, 0xac,
- 0xb5, 0xaa, 0x20, 0xbf, 0xa3, 0xaf, 0xcf, 0x20, 0x3a, 0xf9, 0xd3, 0x67,
- 0x3a, 0xf9, 0x88, 0xcd, 0x1d, 0x7f, 0xcd, 0x5c, 0x37, 0xfa, 0x75, 0x0e,
- 0xa7, 0x3d, 0xa8, 0x21, 0xbd, 0xa4, 0x13, 0xaf, 0xc3, 0x2f, 0x1a, 0xdc,
- 0xea, 0xc3, 0xc4, 0x81, 0xaa, 0x84, 0xcb, 0x3d, 0x2e, 0x17, 0xa0, 0xb2,
- 0x5d, 0xb3, 0x4e, 0xbc, 0x9c, 0x43, 0xab, 0x73, 0x63, 0xf1, 0x7b, 0xef,
- 0x21, 0x8d, 0x1d, 0x7d, 0xef, 0xb9, 0xb9, 0xd7, 0xd0, 0xdd, 0xfd, 0x3a,
- 0xfd, 0xfc, 0x81, 0x91, 0xd4, 0x27, 0x90, 0xa8, 0x8e, 0xff, 0x83, 0x0d,
- 0x06, 0x67, 0xba, 0x3a, 0xff, 0x7a, 0x9b, 0xee, 0xdc, 0xf9, 0xd5, 0xc3,
- 0xed, 0xd1, 0xc5, 0xfc, 0xfb, 0xe9, 0x68, 0xae, 0x75, 0xfd, 0x1b, 0x7b,
- 0x02, 0x03, 0xab, 0xa9, 0xbd, 0xf1, 0xb3, 0xf0, 0x90, 0x9c, 0x45, 0x3c,
- 0x61, 0x7f, 0xdc, 0xf2, 0xf2, 0x9e, 0xce, 0xb9, 0xd4, 0xea, 0x8b, 0xf2,
- 0x39, 0xe8, 0x55, 0xb9, 0x90, 0x9d, 0x65, 0x9d, 0x5b, 0x9a, 0x79, 0xf8,
- 0x5e, 0xfe, 0x8d, 0xda, 0x2e, 0x03, 0xaf, 0xf9, 0xf7, 0x6a, 0x0a, 0xe3,
- 0xe7, 0x54, 0x1f, 0x18, 0x96, 0x5f, 0xa1, 0xb9, 0xb3, 0x9d, 0x7f, 0xf2,
- 0x3e, 0x86, 0x1b, 0xe3, 0x59, 0xd3, 0xaf, 0xff, 0xf2, 0x6b, 0x6c, 0x63,
- 0x04, 0x2a, 0x9e, 0x6c, 0x18, 0xe9, 0xd7, 0xfb, 0x76, 0xe9, 0x96, 0xbe,
- 0xc7, 0x50, 0x13, 0x00, 0x12, 0x6f, 0xa1, 0x85, 0x86, 0xff, 0xff, 0xdc,
- 0x4d, 0xff, 0x9b, 0xff, 0xbd, 0x7f, 0xfb, 0xe4, 0x5b, 0xcc, 0x3a, 0xf8,
- 0x00, 0x81, 0x3a, 0xff, 0xd1, 0xc9, 0x24, 0x78, 0xd4, 0x70, 0xeb, 0xfd,
- 0xc4, 0x52, 0x78, 0x3d, 0x50, 0xeb, 0xfe, 0x76, 0x17, 0xc7, 0x41, 0xd8,
- 0xeb, 0xff, 0xe1, 0xcd, 0x62, 0xde, 0x59, 0xf4, 0xee, 0x1d, 0x6c, 0x92,
- 0x2e, 0xfe, 0x71, 0x38, 0xe2, 0xff, 0xb8, 0x91, 0xee, 0x02, 0x1a, 0x75,
- 0x3a, 0xbd, 0xe0, 0x42, 0x2b, 0x23, 0x20, 0x91, 0xea, 0x38, 0x70, 0x80,
- 0x61, 0xf3, 0xf3, 0x7b, 0xff, 0xb0, 0x7d, 0xcc, 0xee, 0xbe, 0xf8, 0x75,
- 0xff, 0x6f, 0xfc, 0xea, 0x6d, 0x0b, 0x3a, 0xd9, 0xe9, 0xfd, 0x0a, 0x0d,
- 0xff, 0xb1, 0x5e, 0x07, 0xdf, 0x13, 0xf3, 0x50, 0xeb, 0xff, 0xf3, 0x8b,
- 0x73, 0x88, 0xb0, 0x63, 0x2f, 0x9d, 0x3a, 0xfc, 0xf2, 0xe2, 0x32, 0x75,
- 0xfd, 0xee, 0xa4, 0xfd, 0x50, 0xeb, 0xfd, 0x8d, 0xc4, 0x07, 0x10, 0xeb,
- 0xef, 0xb5, 0x7c, 0x3a, 0xf9, 0x14, 0x46, 0x0e, 0xac, 0x3c, 0x41, 0x22,
- 0xbb, 0xc6, 0x1d, 0x7d, 0xa1, 0x75, 0x9d, 0x4e, 0x6d, 0xf7, 0x17, 0xbe,
- 0xce, 0x35, 0x67, 0x53, 0xaa, 0x23, 0x69, 0x3a, 0x88, 0xfc, 0x52, 0x82,
- 0x71, 0x2f, 0xd3, 0xa0, 0x55, 0xe7, 0x88, 0x6d, 0xc3, 0xae, 0xd3, 0x4e,
- 0xaf, 0x4d, 0x30, 0x44, 0x2f, 0xed, 0x99, 0x6c, 0xff, 0xdd, 0x8e, 0xbd,
- 0x19, 0xd3, 0xaf, 0x0e, 0x7c, 0xea, 0xe1, 0xb4, 0x11, 0xab, 0xcf, 0xbe,
- 0x8e, 0xbe, 0x41, 0x6e, 0x1d, 0x7b, 0x68, 0x13, 0xa8, 0x07, 0xac, 0xb1,
- 0xcf, 0x8f, 0xdf, 0xe5, 0x39, 0x9f, 0xe2, 0x7c, 0xeb, 0x93, 0xa7, 0x5f,
- 0xdb, 0x78, 0xda, 0x23, 0x87, 0x52, 0xb4, 0x9c, 0x3b, 0xb5, 0x63, 0xb2,
- 0x17, 0xf0, 0xce, 0x05, 0x6f, 0xfb, 0x00, 0x04, 0xdf, 0x37, 0xf9, 0xd7,
- 0xd2, 0x17, 0x69, 0xd6, 0xdb, 0x87, 0xb3, 0x07, 0x37, 0xff, 0x01, 0xc1,
- 0xd7, 0xfa, 0x49, 0x00, 0x75, 0xf3, 0x2e, 0xa9, 0xa7, 0x5f, 0xf3, 0x3a,
- 0x9d, 0x03, 0xb0, 0x40, 0x75, 0xf6, 0x82, 0x2a, 0x1d, 0x7f, 0x70, 0x3b,
- 0x33, 0xc4, 0x3a, 0xf8, 0x47, 0x3e, 0x75, 0x3a, 0x67, 0x40, 0x28, 0xc4,
- 0x24, 0x24, 0x64, 0xf3, 0x84, 0x5f, 0x2f, 0xbf, 0xbc, 0x32, 0xff, 0x19,
- 0xc7, 0x5f, 0xfe, 0x17, 0x9d, 0xd7, 0xee, 0x27, 0x1c, 0x07, 0x5e, 0x18,
- 0x59, 0xd4, 0xd4, 0x49, 0xe1, 0x8a, 0x24, 0x5a, 0x65, 0x69, 0xd6, 0x80,
- 0xcf, 0x87, 0xca, 0xd8, 0x71, 0xe5, 0x10, 0xed, 0x0e, 0xb6, 0x96, 0x82,
- 0x54, 0xb6, 0x4e, 0x54, 0x29, 0x0b, 0xb9, 0x4a, 0x8d, 0xde, 0x34, 0xe4,
- 0x8c, 0xc1, 0x99, 0x4a, 0x3d, 0x8c, 0x11, 0x70, 0xf7, 0xe4, 0xed, 0x24,
- 0x47, 0x2f, 0xec, 0x6d, 0xd3, 0xf3, 0x70, 0xca, 0x51, 0xd4, 0xe1, 0xd7,
- 0xe5, 0x8e, 0x31, 0x0a, 0x79, 0xe8, 0xea, 0x7c, 0xc7, 0xd8, 0xaa, 0x1e,
- 0xd5, 0x33, 0xaf, 0x5b, 0xe5, 0xad, 0x51, 0xbf, 0xfd, 0x32, 0xe1, 0xb3,
- 0x67, 0x65, 0x11, 0x23, 0x44, 0xd9, 0x7f, 0xa6, 0xce, 0xca, 0x22, 0x46,
- 0x8a, 0xb6, 0xff, 0x35, 0xa1, 0xf8, 0xbb, 0x4e, 0xbe, 0xce, 0x47, 0xce,
- 0xb4, 0xfb, 0x87, 0xa4, 0x26, 0x57, 0xfe, 0xe3, 0xf1, 0xf6, 0xeb, 0xe0,
- 0x0e, 0xbf, 0x3f, 0x57, 0xc0, 0x1d, 0x7a, 0x22, 0x46, 0x8a, 0xd2, 0xfc,
- 0xa6, 0xfa, 0x0e, 0xe7, 0x5b, 0xb2, 0x3d, 0x24, 0x27, 0xbf, 0xfe, 0x93,
- 0xf7, 0x3d, 0x85, 0xc3, 0x5d, 0x24, 0x75, 0xff, 0xf3, 0x75, 0x82, 0xeb,
- 0x8c, 0xff, 0xdd, 0x67, 0x5d, 0xff, 0xba, 0x26, 0x61, 0x36, 0xff, 0xff,
- 0xf3, 0xce, 0x4f, 0xeb, 0x14, 0x97, 0x13, 0xf8, 0xc8, 0xba, 0xf6, 0xc6,
- 0x0e, 0xbe, 0x6f, 0xd3, 0x63, 0xaf, 0xde, 0x7e, 0x2f, 0xe9, 0xd6, 0x7d,
- 0xcf, 0x2e, 0x71, 0x15, 0xfb, 0x38, 0x98, 0xb3, 0xaf, 0xfe, 0x18, 0x49,
- 0x72, 0x03, 0xb7, 0x50, 0xea, 0xd8, 0xf9, 0xf8, 0x4b, 0x7f, 0x9a, 0xfd,
- 0xd9, 0xfb, 0xb1, 0xd7, 0xe6, 0x70, 0x0b, 0x57, 0x3a, 0xfe, 0x17, 0x63,
- 0x76, 0xe8, 0xea, 0x64, 0xf6, 0x55, 0x15, 0xd3, 0xa2, 0xcb, 0x21, 0x1b,
- 0x7f, 0x9b, 0x9f, 0x81, 0xf4, 0x27, 0x5a, 0x69, 0xfd, 0x71, 0x45, 0xca,
- 0xf6, 0x3d, 0xc7, 0x94, 0x86, 0x07, 0x4b, 0x79, 0x0c, 0x58, 0x84, 0x88,
- 0xc3, 0x57, 0xe4, 0xd7, 0xfa, 0x6c, 0xec, 0xa2, 0x24, 0x68, 0xb0, 0x2f,
- 0xdd, 0x94, 0x44, 0x8d, 0x13, 0xad, 0xff, 0xfe, 0xe3, 0xec, 0x0c, 0x5c,
- 0xda, 0xd6, 0x71, 0x34, 0x1d, 0x8e, 0xbf, 0x4c, 0xb8, 0x6c, 0xd8, 0x89,
- 0x66, 0x4c, 0xef, 0xf3, 0x75, 0x32, 0x8a, 0x3a, 0xce, 0xbf, 0x76, 0x51,
- 0x12, 0x34, 0x5b, 0x37, 0xff, 0xfa, 0x1b, 0x36, 0x9d, 0x30, 0x09, 0x9a,
- 0xcf, 0x8b, 0x9d, 0x7f, 0xef, 0x5f, 0x53, 0x71, 0x25, 0x1d, 0x3a, 0xff,
- 0x9d, 0xaf, 0xdd, 0x9f, 0xbb, 0x1d, 0x69, 0xb1, 0x30, 0x75, 0x99, 0xc2,
- 0xe0, 0x9f, 0xdf, 0xff, 0xa3, 0xdf, 0x43, 0xa9, 0xb3, 0xb1, 0xae, 0x43,
- 0x4e, 0xbe, 0x94, 0x44, 0x8d, 0x17, 0x35, 0x96, 0x75, 0x74, 0xde, 0xb0,
- 0x5b, 0x73, 0x2b, 0x3a, 0xd3, 0x61, 0xb9, 0x60, 0x8a, 0xfd, 0xd9, 0x44,
- 0x48, 0xd1, 0x77, 0xdf, 0xe6, 0xcd, 0xae, 0xf5, 0x18, 0x3a, 0xd3, 0x61,
- 0xf4, 0x41, 0x9d, 0xf4, 0xca, 0x03, 0xd3, 0xa9, 0xdd, 0xce, 0xee, 0x5a,
- 0xf8, 0x69, 0x1a, 0xee, 0xae, 0x93, 0x9c, 0x5d, 0x85, 0x52, 0xe1, 0xab,
- 0x08, 0x5e, 0xc6, 0x7a, 0x28, 0x5a, 0x86, 0x6f, 0xe1, 0x21, 0xe4, 0x9e,
- 0xfd, 0xad, 0x2e, 0x1a, 0x75, 0xda, 0x73, 0xaf, 0xfe, 0xde, 0x41, 0x8d,
- 0xff, 0x98, 0x2a, 0x1d, 0x78, 0x62, 0x67, 0x44, 0x0e, 0x89, 0xfe, 0x2b,
- 0x78, 0x30, 0xb3, 0xaf, 0xed, 0xb1, 0x57, 0xdd, 0x43, 0xab, 0xa7, 0x96,
- 0x23, 0x77, 0xfe, 0xd4, 0x29, 0xc4, 0x71, 0x0b, 0x9d, 0x7f, 0xee, 0x47,
- 0xe3, 0x9b, 0xb7, 0x3e, 0x75, 0x61, 0xfd, 0x21, 0xe5, 0xd1, 0xe9, 0xd7,
- 0xff, 0xff, 0x86, 0x18, 0x1c, 0xff, 0xf3, 0x67, 0x18, 0x53, 0x4b, 0x7c,
- 0x10, 0x1d, 0x58, 0x88, 0xae, 0x8b, 0x5f, 0xee, 0x60, 0x12, 0x77, 0x70,
- 0xeb, 0xe9, 0x44, 0x48, 0xd1, 0x2b, 0xdf, 0xfe, 0xff, 0x31, 0xb2, 0xe2,
- 0x01, 0xc7, 0xe7, 0x53, 0x51, 0x51, 0xd3, 0x31, 0x2d, 0xb9, 0xbb, 0x1d,
- 0x7f, 0xe1, 0x86, 0x01, 0xc7, 0xdb, 0x18, 0x3a, 0xff, 0xfe, 0x6e, 0x27,
- 0xb8, 0xb4, 0xfe, 0x9d, 0x71, 0xbf, 0xce, 0xbe, 0x0c, 0x75, 0xa7, 0x5f,
- 0xf3, 0xc8, 0x5f, 0x6f, 0x63, 0xe7, 0x5f, 0xff, 0xe4, 0xfc, 0x2e, 0x07,
- 0xde, 0x31, 0x03, 0xb4, 0x93, 0x63, 0xa8, 0x08, 0xba, 0x42, 0x18, 0x38,
- 0xa0, 0x27, 0x03, 0x87, 0xfc, 0x8c, 0x52, 0xff, 0xdf, 0x86, 0xeb, 0x8f,
- 0xdf, 0x20, 0x3a, 0xff, 0xef, 0xa4, 0xe4, 0xfb, 0x2d, 0x71, 0xf9, 0xd7,
- 0xff, 0xa3, 0x1b, 0xcc, 0x41, 0xcf, 0x67, 0xb0, 0xeb, 0xd0, 0xd9, 0x9d,
- 0x73, 0x69, 0xb0, 0x9b, 0x04, 0x2a, 0xb2, 0x19, 0x4b, 0x2f, 0xd4, 0x73,
- 0x1f, 0x36, 0xf2, 0x80, 0xa9, 0x16, 0xff, 0xf6, 0x72, 0x61, 0xc0, 0x20,
- 0xff, 0x38, 0x75, 0xef, 0xb8, 0x0a, 0xbf, 0xfd, 0xc8, 0x4f, 0xbb, 0x53,
- 0xbb, 0x07, 0xd2, 0xaf, 0xf4, 0x4a, 0x60, 0x76, 0x7e, 0x99, 0xcf, 0x97,
- 0x43, 0x76, 0x9a, 0x4b, 0xe1, 0x8b, 0x9d, 0x65, 0xfc, 0x2a, 0xa7, 0x42,
- 0xb2, 0xff, 0xf4, 0xcb, 0x86, 0xcd, 0x9d, 0x94, 0x44, 0x8d, 0x13, 0x0d,
- 0xff, 0xfd, 0x93, 0xa0, 0x1c, 0x79, 0xbf, 0xcc, 0x00, 0x7f, 0xa3, 0xaf,
- 0xff, 0x76, 0x3d, 0x99, 0x4f, 0xb5, 0x87, 0xd3, 0x4e, 0xbb, 0x26, 0x14,
- 0x55, 0xf9, 0x5d, 0xbf, 0xfa, 0x7d, 0xcd, 0xda, 0x18, 0xf8, 0xbb, 0x4e,
- 0xbf, 0x62, 0xfc, 0x6e, 0xae, 0x75, 0xfc, 0xeb, 0xcf, 0x5e, 0x71, 0xd4,
- 0x03, 0xdb, 0xe1, 0x6d, 0xfb, 0x8e, 0x04, 0x50, 0xea, 0x43, 0xc9, 0x54,
- 0x45, 0x7f, 0x9e, 0x36, 0xfa, 0x91, 0xd3, 0xaf, 0xd1, 0xd6, 0xc2, 0xce,
- 0xa1, 0x3d, 0x90, 0x99, 0xdf, 0xff, 0x93, 0xbc, 0x8f, 0x00, 0xc6, 0xf1,
- 0xe7, 0x01, 0xce, 0xbf, 0xfb, 0x37, 0x63, 0xcf, 0x1e, 0x5c, 0x46, 0x4e,
- 0xae, 0x22, 0x7c, 0x55, 0xef, 0xe5, 0xbe, 0x0f, 0xe7, 0x8e, 0xb6, 0x8e,
- 0xbf, 0x3e, 0x0f, 0xe7, 0x8e, 0xbf, 0xb8, 0x9f, 0xd4, 0x6f, 0xe0, 0xf9,
- 0x99, 0x2e, 0x58, 0x85, 0xfe, 0x6f, 0xdd, 0x73, 0xbd, 0x69, 0xd7, 0xff,
- 0xf9, 0x85, 0x5f, 0xce, 0x78, 0x1c, 0xd9, 0x30, 0x77, 0x6e, 0x8e, 0xbf,
- 0x31, 0xfc, 0xe4, 0x8e, 0xb0, 0xe2, 0x23, 0x61, 0x96, 0xff, 0xf7, 0xc6,
- 0x3d, 0xe6, 0x20, 0x03, 0xfd, 0x1d, 0x7f, 0xcf, 0xb7, 0x96, 0xf0, 0x31,
- 0xb1, 0xd4, 0xe8, 0x85, 0xea, 0x4d, 0xfd, 0x3b, 0xcf, 0xc5, 0xfd, 0x3a,
- 0xff, 0xf3, 0xff, 0xd7, 0x6e, 0x6f, 0xfd, 0x82, 0xc1, 0xd4, 0xe7, 0xfc,
- 0x86, 0x37, 0xfb, 0xd8, 0xf7, 0xbd, 0x4e, 0x9d, 0x7f, 0x69, 0x14, 0x5c,
- 0x7c, 0xeb, 0xff, 0xff, 0x77, 0x27, 0x38, 0xff, 0xc7, 0x91, 0x7e, 0x42,
- 0x7d, 0xff, 0xa3, 0xaf, 0xe1, 0xcd, 0x78, 0x94, 0xfe, 0x75, 0x6e, 0x8c,
- 0xee, 0x96, 0xce, 0x6e, 0xbe, 0xf1, 0x39, 0x56, 0xc7, 0x56, 0x1e, 0xe2,
- 0x86, 0x77, 0xff, 0xc1, 0x9f, 0x85, 0xd7, 0x09, 0xc8, 0xff, 0x1c, 0xeb,
- 0xfc, 0xe3, 0xf8, 0x5a, 0x7c, 0xea, 0xc4, 0x40, 0xf1, 0x46, 0xff, 0xfd,
- 0xc1, 0xcf, 0xf1, 0x33, 0x7f, 0xe4, 0xe7, 0xd1, 0xd7, 0xff, 0x40, 0xf1,
- 0xd0, 0x09, 0xac, 0x69, 0xd7, 0x9f, 0xdf, 0x27, 0x56, 0x22, 0xce, 0x15,
- 0x45, 0x02, 0xf7, 0x90, 0x61, 0xd7, 0xa7, 0xed, 0x4f, 0xe7, 0x54, 0x1e,
- 0x1e, 0x87, 0x6f, 0xf0, 0xc3, 0x0f, 0xfc, 0xd8, 0xeb, 0x4d, 0x3f, 0xb2,
- 0x33, 0x1e, 0x1d, 0x80, 0x7c, 0xc8, 0x60, 0x4a, 0x11, 0x1b, 0xaa, 0xb3,
- 0x0c, 0x3e, 0xc2, 0xaf, 0x90, 0xa0, 0xf4, 0x80, 0x63, 0x5e, 0xd4, 0x28,
- 0xff, 0x0d, 0x50, 0xb8, 0x4f, 0x10, 0xdf, 0xff, 0x75, 0x37, 0x6e, 0x93,
- 0xfc, 0x7e, 0xfd, 0xce, 0xbf, 0x76, 0x51, 0x12, 0x34, 0x55, 0xd7, 0xba,
- 0xeb, 0x3a, 0xff, 0x9b, 0x36, 0x76, 0x51, 0x12, 0x34, 0x47, 0x97, 0xfc,
- 0xed, 0x7e, 0xec, 0xfd, 0xd8, 0xeb, 0x4c, 0x04, 0xc6, 0xf1, 0x3f, 0xa6,
- 0x70, 0x36, 0x28, 0xb7, 0xee, 0xca, 0x22, 0x46, 0x8b, 0x06, 0xf2, 0x8f,
- 0xb1, 0xd7, 0xff, 0xf0, 0x86, 0x36, 0x5e, 0x4f, 0x07, 0xb9, 0xd6, 0xf9,
- 0x69, 0xd7, 0xec, 0x1c, 0xfe, 0x8e, 0xbf, 0xdd, 0x85, 0xf9, 0xec, 0x6e,
- 0x75, 0xa6, 0xc4, 0xc2, 0x94, 0x33, 0x90, 0xec, 0x30, 0x79, 0x25, 0xbf,
- 0xd3, 0x67, 0x65, 0x11, 0x23, 0x45, 0x95, 0x7e, 0xec, 0xa2, 0x24, 0x68,
- 0xb4, 0xef, 0xfa, 0x01, 0xc8, 0x67, 0x88, 0xb3, 0xad, 0x36, 0x1f, 0x5a,
- 0xcc, 0xef, 0xca, 0xd9, 0x5b, 0xd5, 0xa5, 0x6a, 0x7c, 0x3a, 0xff, 0xa7,
- 0xfe, 0x23, 0x00, 0x88, 0x91, 0xd7, 0xe5, 0x6d, 0x3e, 0xeb, 0x1c, 0xeb,
- 0xfd, 0xe5, 0x79, 0xfd, 0x26, 0x8e, 0xb2, 0x1d, 0x53, 0xf9, 0xe1, 0xcf,
- 0x1a, 0x5f, 0xff, 0xc9, 0xc8, 0x1f, 0xb7, 0x3b, 0x8e, 0x23, 0x9f, 0x3a,
- 0xfd, 0x3a, 0x01, 0x8b, 0x3a, 0xf9, 0x6f, 0xbe, 0x8e, 0xa6, 0xa2, 0x7f,
- 0x15, 0x59, 0x28, 0xbf, 0xd9, 0xaf, 0x1d, 0xe8, 0x78, 0x75, 0xff, 0xf9,
- 0xc6, 0x5c, 0x4e, 0x27, 0x5d, 0x96, 0x33, 0x87, 0x5f, 0x3f, 0x97, 0xe1,
- 0xd7, 0xd2, 0x88, 0x91, 0xa2, 0xdc, 0xbf, 0xf6, 0x77, 0x07, 0xc7, 0x33,
- 0x76, 0x0e, 0xbf, 0x0f, 0xb1, 0xbe, 0x8e, 0xa7, 0x3e, 0x88, 0x40, 0xad,
- 0xd1, 0xaf, 0xd2, 0x2d, 0x42, 0x56, 0xff, 0x40, 0xfa, 0xc8, 0xba, 0xce,
- 0xbc, 0xb1, 0x43, 0xac, 0x27, 0x5f, 0xf7, 0x03, 0x1a, 0xcc, 0x15, 0x0e,
- 0xbf, 0x6a, 0x37, 0x80, 0x1d, 0x64, 0x01, 0xef, 0x7c, 0xde, 0x9d, 0x15,
- 0xd8, 0x35, 0xc6, 0xdb, 0xfe, 0xcf, 0xfd, 0x36, 0x5b, 0x89, 0xd7, 0xfc,
- 0xe2, 0x15, 0xbe, 0xbe, 0x87, 0x5f, 0x01, 0xf3, 0xa7, 0x5f, 0xbc, 0x6f,
- 0xa4, 0x50, 0xeb, 0x46, 0xc7, 0x97, 0xb9, 0x05, 0xff, 0xcd, 0xce, 0x27,
- 0x41, 0xc7, 0x19, 0x1d, 0x7f, 0xb7, 0x6b, 0x8f, 0xf3, 0xd3, 0xaf, 0xb5,
- 0xea, 0x7c, 0xea, 0x84, 0x60, 0x68, 0xa4, 0x28, 0x5e, 0x4c, 0xef, 0xfe,
- 0xfa, 0x7a, 0xed, 0x07, 0x1c, 0x64, 0x75, 0x1d, 0x78, 0x31, 0xf3, 0xae,
- 0x0b, 0x9d, 0x4d, 0x36, 0x1f, 0x1b, 0xa3, 0xaf, 0xb7, 0x92, 0x74, 0xeb,
- 0xce, 0xb9, 0xb1, 0x10, 0xfb, 0x9d, 0x2c, 0x87, 0xe1, 0x54, 0xe9, 0x8c,
- 0xa4, 0x32, 0xaf, 0x0f, 0xe7, 0x8e, 0xbf, 0xe6, 0xcd, 0x9d, 0x94, 0x44,
- 0x8d, 0x14, 0x3d, 0x21, 0xf1, 0xc0, 0xf5, 0xfb, 0xd7, 0x96, 0x2c, 0xeb,
- 0xe7, 0x67, 0x00, 0x75, 0x9f, 0xa7, 0x91, 0xa2, 0x7b, 0xff, 0x40, 0x1c,
- 0x1c, 0x41, 0x45, 0x9d, 0x7f, 0xf6, 0x9c, 0x59, 0xc1, 0xf6, 0x3f, 0x87,
- 0x5f, 0xed, 0x06, 0x59, 0xf1, 0x73, 0xa9, 0x68, 0xae, 0xe1, 0xdf, 0xd0,
- 0xaf, 0xfe, 0x0b, 0x79, 0x1d, 0xdf, 0xee, 0x9b, 0x1d, 0x7f, 0xce, 0xd7,
- 0xee, 0xcf, 0xdd, 0x8e, 0xbf, 0x27, 0xf5, 0x08, 0x75, 0xff, 0x77, 0xde,
- 0xc0, 0xff, 0x3d, 0x3a, 0xbd, 0x3d, 0xe0, 0x92, 0xdf, 0xfd, 0x21, 0x7f,
- 0x8e, 0x4e, 0xce, 0xb4, 0xeb, 0xfc, 0x23, 0x1f, 0xf2, 0xf2, 0x3a, 0xf8,
- 0x7d, 0xdb, 0xd3, 0xab, 0x0f, 0x59, 0x0c, 0xaf, 0xfc, 0x9b, 0xeb, 0xc7,
- 0xfc, 0x03, 0x04, 0xeb, 0xf4, 0x6f, 0xaf, 0xa1, 0xd5, 0x89, 0x91, 0x72,
- 0x13, 0x22, 0x41, 0xa4, 0x2b, 0xf4, 0x05, 0x47, 0xf2, 0x75, 0xfa, 0x7f,
- 0xce, 0xbe, 0x8e, 0xa6, 0x4f, 0x50, 0x4a, 0x6f, 0xfa, 0x34, 0xec, 0xee,
- 0xdc, 0x9c, 0x75, 0xff, 0xf8, 0x1c, 0x7f, 0x33, 0x7c, 0x63, 0xdd, 0x69,
- 0xfd, 0x2a, 0xe0, 0x61, 0xd5, 0x87, 0xdc, 0x8b, 0x37, 0xfb, 0x91, 0xeb,
- 0x22, 0xe0, 0x3a, 0xd3, 0x2b, 0x2c, 0xd2, 0xc9, 0xf1, 0x11, 0x5b, 0xcf,
- 0x55, 0x8b, 0xa3, 0xc3, 0x25, 0xa6, 0x00, 0x35, 0xc8, 0xca, 0xd4, 0x36,
- 0x94, 0x38, 0x37, 0x2e, 0x43, 0x76, 0x63, 0x41, 0xec, 0x6a, 0xeb, 0x84,
- 0x57, 0x1a, 0x22, 0x1a, 0xbe, 0x98, 0x0a, 0x2e, 0xa1, 0x2f, 0xf8, 0xd1,
- 0x43, 0x09, 0x59, 0xc4, 0x53, 0xd0, 0xa9, 0xf2, 0x41, 0x7f, 0xa6, 0xce,
- 0xca, 0x22, 0x46, 0x8b, 0xce, 0x9d, 0xbe, 0x1b, 0x6a, 0xd8, 0x23, 0x02,
- 0xca, 0x47, 0xe6, 0xf2, 0x8a, 0x3b, 0x1a, 0xca, 0xd4, 0xf9, 0x0a, 0xa1,
- 0xa6, 0xaa, 0x4e, 0x8e, 0xc6, 0xff, 0x4d, 0x9d, 0x94, 0x44, 0x8d, 0x14,
- 0xb5, 0xfb, 0xb2, 0x88, 0x91, 0xa2, 0xc2, 0xbf, 0xff, 0x3e, 0x08, 0x1f,
- 0x8f, 0xbf, 0xf0, 0x61, 0x67, 0x5f, 0xc1, 0xea, 0x6d, 0x0b, 0x3a, 0xd3,
- 0x62, 0x2c, 0x56, 0x67, 0x3c, 0xa3, 0x7f, 0xa6, 0xce, 0xca, 0x22, 0x46,
- 0x8b, 0x2e, 0xee, 0xa8, 0x75, 0xf4, 0xca, 0x2b, 0x15, 0x64, 0xeb, 0xd3,
- 0x79, 0x59, 0xd5, 0x23, 0xce, 0x09, 0x7d, 0x0a, 0x21, 0xf4, 0xcb, 0x6f,
- 0x4e, 0xb9, 0x4d, 0x8e, 0xba, 0x3a, 0xd3, 0x53, 0x82, 0x37, 0xfd, 0x1b,
- 0x8e, 0x6f, 0xf7, 0x50, 0xeb, 0xfd, 0xb6, 0xfa, 0x70, 0x7d, 0x0e, 0xbf,
- 0x3e, 0x4e, 0x7d, 0x1d, 0x67, 0x83, 0xdb, 0x60, 0xd2, 0xa1, 0x17, 0x63,
- 0x09, 0x4b, 0xe8, 0x6b, 0x40, 0x75, 0xfd, 0x1d, 0x7f, 0xc7, 0x0e, 0xbc,
- 0xc3, 0x0c, 0x15, 0x7f, 0xce, 0xdd, 0xff, 0xd7, 0xcd, 0xca, 0x98, 0xbf,
- 0xb9, 0xf4, 0x75, 0x01, 0x19, 0x3c, 0x21, 0x14, 0xa9, 0xc9, 0x37, 0xf2,
- 0x46, 0xbd, 0xd0, 0x4e, 0xbf, 0xff, 0xb8, 0x9f, 0xe6, 0x68, 0x71, 0x61,
- 0xd7, 0x21, 0xa7, 0x5f, 0xe7, 0x6f, 0xe3, 0x90, 0x03, 0xab, 0x11, 0x15,
- 0xd5, 0x9b, 0x34, 0xeb, 0x34, 0xeb, 0x34, 0xea, 0x73, 0x60, 0xa0, 0x82,
- 0x08, 0x5f, 0xff, 0xbf, 0xa4, 0x96, 0x0f, 0x5c, 0x70, 0x18, 0xa1, 0xd6,
- 0xdc, 0xeb, 0xb4, 0x13, 0xab, 0x0f, 0xe7, 0x4a, 0x5f, 0x11, 0xb9, 0x1c,
- 0xeb, 0xf8, 0x5d, 0x62, 0xf8, 0x75, 0xcd, 0x73, 0xa8, 0x07, 0xa4, 0xc8,
- 0xa0, 0x4a, 0x6f, 0xff, 0xff, 0xb8, 0xff, 0xd2, 0x6b, 0x4f, 0xfe, 0x23,
- 0xf7, 0xd5, 0xc3, 0x5b, 0xf5, 0x0e, 0xb9, 0x37, 0x3a, 0xe7, 0x59, 0xd7,
- 0xff, 0xf3, 0x5c, 0x42, 0xd6, 0xbf, 0xf9, 0x8b, 0xf2, 0xfe, 0x9d, 0x74,
- 0xa6, 0x75, 0xdc, 0x2d, 0x92, 0xc1, 0x0e, 0x6c, 0x87, 0x7c, 0x8f, 0xbb,
- 0x0b, 0x78, 0x52, 0x18, 0x53, 0x6a, 0x10, 0x1f, 0x30, 0x9c, 0xfd, 0x3c,
- 0x2d, 0xe4, 0x56, 0xff, 0xf4, 0xcb, 0x86, 0xcd, 0x9d, 0x94, 0x44, 0x8d,
- 0x14, 0x65, 0xfa, 0x73, 0xf5, 0xfd, 0x3a, 0xfc, 0x31, 0xeb, 0xf9, 0x3a,
- 0xff, 0xed, 0xe4, 0x9d, 0xe6, 0x60, 0xb7, 0x47, 0x5a, 0x67, 0x44, 0xa7,
- 0x0a, 0x7e, 0x51, 0x4d, 0x64, 0xd8, 0xf6, 0x1e, 0x0b, 0x39, 0x89, 0xe8,
- 0x8d, 0x43, 0x7f, 0xf0, 0xeb, 0xbf, 0xfa, 0x68, 0x6c, 0xd9, 0xd9, 0x44,
- 0x48, 0xd1, 0x1c, 0xdf, 0xfe, 0x99, 0x70, 0xd9, 0xb3, 0xb2, 0x88, 0x91,
- 0xa2, 0x72, 0xbf, 0xd3, 0x67, 0x65, 0x11, 0x23, 0x45, 0x99, 0x7f, 0xcd,
- 0xd4, 0x2e, 0x6e, 0x7f, 0xd3, 0xaf, 0xf9, 0x58, 0x03, 0x16, 0xfb, 0xba,
- 0xce, 0xbf, 0xef, 0x7a, 0xff, 0xe4, 0x6e, 0xd3, 0xaf, 0xf6, 0x6b, 0xbd,
- 0xcd, 0xf4, 0x75, 0xdb, 0xac, 0xeb, 0x4c, 0xac, 0xa3, 0x09, 0xcf, 0x9a,
- 0x75, 0x3c, 0x67, 0x7f, 0xa6, 0xce, 0xca, 0x22, 0x46, 0x8b, 0x76, 0xfe,
- 0x18, 0x9b, 0xbb, 0x70, 0xeb, 0xc9, 0xbf, 0xa7, 0x5f, 0xfa, 0x1b, 0x36,
- 0x76, 0x51, 0x12, 0x34, 0x52, 0x16, 0x9a, 0x48, 0x95, 0xe9, 0x72, 0xc7,
- 0x6f, 0xfe, 0x9a, 0x1b, 0x36, 0x76, 0x51, 0x12, 0x34, 0x4a, 0x55, 0xb2,
- 0xb8, 0xb6, 0x54, 0x56, 0xaf, 0x07, 0xfe, 0xc3, 0xf4, 0x52, 0xff, 0x0d,
- 0x45, 0x46, 0xf7, 0xe9, 0x93, 0x41, 0x59, 0xd7, 0x86, 0x1a, 0x75, 0xff,
- 0xa1, 0xb3, 0x67, 0x65, 0x11, 0x23, 0x44, 0xed, 0x76, 0xca, 0xe7, 0x5f,
- 0xff, 0x90, 0x01, 0x5b, 0xaa, 0x80, 0x0b, 0x8e, 0x48, 0xeb, 0xfe, 0x76,
- 0xbf, 0x76, 0x7e, 0xec, 0x75, 0xa6, 0xc4, 0xc2, 0x96, 0x35, 0xc4, 0xa8,
- 0x1a, 0x15, 0x3b, 0xff, 0xe9, 0xbc, 0xcf, 0x40, 0xfb, 0x9f, 0x71, 0x4f,
- 0x4e, 0xbf, 0xfa, 0x17, 0xcc, 0x94, 0x71, 0xfc, 0xb4, 0xeb, 0xff, 0x87,
- 0x39, 0x1b, 0x66, 0x86, 0x37, 0x3a, 0xe9, 0xe9, 0x80, 0x88, 0x6d, 0x22,
- 0x53, 0x55, 0x47, 0x2e, 0x33, 0x2d, 0x27, 0xcf, 0x43, 0x6a, 0xff, 0xfe,
- 0x04, 0x7e, 0x6c, 0xd3, 0x8e, 0xfe, 0xeb, 0x4f, 0xe9, 0xd7, 0xee, 0xca,
- 0x22, 0x46, 0x88, 0xb2, 0xff, 0xd0, 0xd9, 0xb3, 0xb2, 0x88, 0x91, 0xa2,
- 0x5d, 0xbf, 0xff, 0xb0, 0x1c, 0x7f, 0x33, 0x7c, 0x63, 0xdd, 0x69, 0xfd,
- 0x2a, 0xd3, 0x62, 0x36, 0xd6, 0x67, 0x3c, 0x95, 0x7f, 0xfa, 0x65, 0xc3,
- 0x66, 0xce, 0xca, 0x22, 0x46, 0x89, 0x8a, 0xfd, 0xd9, 0x44, 0x48, 0xd1,
- 0x54, 0xdb, 0x0e, 0xac, 0x3c, 0x25, 0x0c, 0xef, 0xff, 0xff, 0x76, 0x39,
- 0xbb, 0x73, 0xf3, 0x72, 0x35, 0xd4, 0x63, 0xfc, 0x4e, 0xb4, 0xea, 0x99,
- 0x13, 0x90, 0x45, 0x7f, 0xfa, 0x65, 0xc3, 0x66, 0xce, 0xca, 0x22, 0x46,
- 0x89, 0xd2, 0xff, 0x24, 0x75, 0xdb, 0x13, 0x8e, 0xbf, 0x32, 0xec, 0xbe,
- 0x8e, 0xbf, 0x98, 0xc4, 0x9d, 0x82, 0x75, 0x21, 0xea, 0xe8, 0xa2, 0xf2,
- 0x71, 0xce, 0x98, 0xd0, 0xdf, 0xfc, 0x1d, 0x7d, 0xf7, 0x98, 0x2c, 0xa2,
- 0xce, 0xa5, 0x9f, 0x97, 0x0a, 0xef, 0xfd, 0x0d, 0x9b, 0x3b, 0x28, 0x89,
- 0x1a, 0x27, 0x7b, 0xf7, 0xc3, 0x0b, 0x42, 0xaf, 0xfc, 0x2f, 0xfc, 0xd6,
- 0x66, 0xed, 0x3a, 0x80, 0x9f, 0x46, 0x46, 0x34, 0xb2, 0x28, 0x4a, 0xf9,
- 0x35, 0xfc, 0xf3, 0x7a, 0x38, 0x03, 0xaa, 0x63, 0xfc, 0x14, 0xfb, 0xff,
- 0xd3, 0x2e, 0x1b, 0x36, 0x76, 0x51, 0x12, 0x34, 0x50, 0xb7, 0xff, 0xff,
- 0xb8, 0x15, 0xae, 0x1b, 0x34, 0xb8, 0x1f, 0xb8, 0xe6, 0xca, 0x05, 0xd9,
- 0x3a, 0xfc, 0x1d, 0xfe, 0x92, 0x3a, 0xfd, 0x9e, 0xe4, 0x09, 0xd7, 0x9f,
- 0xd9, 0xb6, 0x3c, 0xd1, 0x28, 0xa4, 0x47, 0xe8, 0xc3, 0x22, 0xff, 0xf4,
- 0xcb, 0x86, 0xcd, 0x9d, 0x94, 0x44, 0x8d, 0x14, 0x95, 0xff, 0xfe, 0xcd,
- 0x4d, 0xe7, 0x19, 0xe4, 0x2f, 0xfc, 0x7f, 0x85, 0x67, 0x53, 0xaf, 0xed,
- 0xed, 0x19, 0xc3, 0x4e, 0x65, 0x19, 0xaf, 0x48, 0xd7, 0x2a, 0xef, 0xd2,
- 0x2f, 0xc6, 0xa8, 0x12, 0x69, 0xe5, 0x7b, 0xfd, 0x36, 0x76, 0x51, 0x12,
- 0x34, 0x44, 0x97, 0xff, 0xa6, 0x5c, 0x36, 0x6c, 0xec, 0xa2, 0x24, 0x68,
- 0x97, 0xaf, 0xba, 0x1f, 0xe8, 0xeb, 0xf7, 0x7d, 0x5a, 0x68, 0xeb, 0xfc,
- 0x83, 0xff, 0x2b, 0x17, 0x3a, 0xff, 0xf7, 0x27, 0x38, 0xfa, 0xaf, 0x80,
- 0xce, 0xee, 0x75, 0xcf, 0xf3, 0xaf, 0xff, 0x04, 0x09, 0xdf, 0x2c, 0xaa,
- 0x0c, 0x0b, 0x27, 0x53, 0x51, 0xca, 0x86, 0x5e, 0xa7, 0xe8, 0x56, 0xff,
- 0xe8, 0x67, 0x4f, 0x3a, 0x38, 0xfb, 0xb2, 0x75, 0xff, 0xcc, 0xf8, 0xf2,
- 0x2f, 0x3a, 0x27, 0x3b, 0x27, 0x51, 0xd7, 0xf3, 0x2d, 0x8f, 0xc4, 0xe3,
- 0xa9, 0xd1, 0x0b, 0x89, 0x90, 0x15, 0x77, 0x5c, 0xea, 0x02, 0xa7, 0xa4,
- 0x22, 0x66, 0x30, 0xde, 0x9e, 0xce, 0x86, 0x62, 0xa2, 0xdb, 0xfe, 0x48,
- 0x10, 0xfd, 0x97, 0x50, 0xeb, 0xff, 0xe4, 0xef, 0x8e, 0x3a, 0x7f, 0x41,
- 0x90, 0x5c, 0xeb, 0xe4, 0xdb, 0xd5, 0x73, 0xaf, 0xa5, 0x11, 0x23, 0x45,
- 0x2f, 0x4a, 0x22, 0x8d, 0x95, 0x0e, 0x93, 0x5f, 0x87, 0xfb, 0x63, 0x07,
- 0x5f, 0xf9, 0xc5, 0xf9, 0xe0, 0x22, 0x19, 0x1d, 0x78, 0x31, 0xa3, 0xaf,
- 0xb5, 0x9f, 0xd1, 0xd4, 0x03, 0xfa, 0x64, 0xfb, 0xe3, 0x77, 0xfd, 0xee,
- 0xba, 0xfb, 0xb5, 0x16, 0x75, 0xef, 0xc4, 0xe3, 0xaf, 0xfa, 0x36, 0xf1,
- 0xb0, 0x59, 0x75, 0x73, 0xa9, 0xd1, 0x2f, 0x07, 0x41, 0x1d, 0xbf, 0xe4,
- 0xd3, 0x28, 0x3f, 0x7f, 0x4e, 0xa6, 0x9f, 0x32, 0xcb, 0xae, 0x81, 0x3a,
- 0xff, 0x9f, 0xdf, 0x1c, 0x75, 0xc0, 0x9d, 0x6e, 0xee, 0x79, 0xb3, 0x85,
- 0x2b, 0x11, 0x34, 0x8d, 0xf7, 0xba, 0xeb, 0x3a, 0xfe, 0x71, 0x67, 0xe8,
- 0xa1, 0xd7, 0xf7, 0x7d, 0x79, 0x62, 0xce, 0xb9, 0xb8, 0x75, 0xe7, 0xf7,
- 0x47, 0x53, 0x9e, 0xf0, 0x0b, 0x58, 0x15, 0xbf, 0x70, 0x2a, 0x60, 0x9d,
- 0x7f, 0xcf, 0xcd, 0x47, 0xdf, 0xaa, 0x8e, 0xbf, 0xf2, 0xe0, 0x1e, 0x59,
- 0x6b, 0x8e, 0xe7, 0x50, 0x0f, 0xe9, 0x0e, 0x6f, 0xbb, 0xef, 0x99, 0xc7,
- 0x5e, 0x46, 0x3e, 0x75, 0x70, 0xf0, 0xf4, 0x4f, 0x40, 0x4c, 0x9f, 0x90,
- 0xa1, 0xfb, 0x25, 0xff, 0xf9, 0xda, 0x2f, 0xb7, 0x96, 0x75, 0xcc, 0x55,
- 0xdf, 0x4e, 0xbf, 0xbc, 0x2f, 0x3f, 0x1f, 0x3a, 0xd2, 0x3a, 0xed, 0xf5,
- 0x86, 0xfa, 0x0b, 0xa9, 0x68, 0xc5, 0x88, 0x4c, 0xdf, 0xec, 0x61, 0xa9,
- 0xa0, 0xac, 0xeb, 0xa7, 0x68, 0xeb, 0xf6, 0x6d, 0x9c, 0xd1, 0xd4, 0xe6,
- 0xfc, 0x46, 0x2f, 0x67, 0x74, 0x75, 0x48, 0xdd, 0x4e, 0x1f, 0xbf, 0xef,
- 0x5f, 0xdf, 0x33, 0x9c, 0x55, 0x1d, 0x4e, 0x98, 0x76, 0x42, 0xb1, 0x08,
- 0xef, 0xff, 0xfe, 0xe3, 0xf7, 0x79, 0x26, 0xfe, 0x14, 0x8f, 0x1a, 0xe4,
- 0x49, 0xc4, 0x07, 0x5f, 0xe1, 0x78, 0x1f, 0xe0, 0x9d, 0x7f, 0xb9, 0x0c,
- 0xa7, 0x5f, 0x63, 0xae, 0xc5, 0x9d, 0x40, 0x47, 0x6a, 0xdd, 0xe0, 0xba,
- 0x71, 0x9d, 0xf9, 0x52, 0x2d, 0xf4, 0x75, 0xfa, 0x27, 0x67, 0x74, 0x75,
- 0x00, 0xf4, 0x16, 0x51, 0x7e, 0xe4, 0x0a, 0x2c, 0xea, 0x73, 0xc7, 0xc2,
- 0x2b, 0xbd, 0x91, 0xd6, 0xd1, 0xd7, 0x22, 0x9a, 0x34, 0xe1, 0x17, 0xbe,
- 0x7f, 0x62, 0x47, 0x5a, 0x67, 0x65, 0x5a, 0x81, 0xa3, 0x21, 0xb7, 0xb9,
- 0x92, 0x42, 0x89, 0x98, 0xf1, 0xfa, 0x42, 0xb1, 0xbe, 0x42, 0x2e, 0x23,
- 0x56, 0xf6, 0x1f, 0x63, 0x19, 0xae, 0xa3, 0x20, 0xfc, 0x35, 0x67, 0x91,
- 0xfc, 0x96, 0xdf, 0xe9, 0xb3, 0xb2, 0x88, 0x91, 0xa2, 0x9c, 0xbf, 0xf2,
- 0x76, 0x35, 0xcc, 0xc1, 0x91, 0xd7, 0xff, 0xee, 0x07, 0xfd, 0x7f, 0xeb,
- 0x25, 0xa7, 0xec, 0x8e, 0xbf, 0xc8, 0xb0, 0x3e, 0x82, 0x27, 0x5f, 0xd9,
- 0xfd, 0xda, 0xec, 0x1d, 0x7f, 0xf2, 0x89, 0xbe, 0x87, 0x01, 0xc8, 0x60,
- 0xeb, 0xff, 0x67, 0x1f, 0xb9, 0x33, 0x0c, 0x30, 0x55, 0xc8, 0xc1, 0xd7,
- 0x6d, 0x30, 0x13, 0x8b, 0x91, 0xdf, 0x15, 0x44, 0xc7, 0xe5, 0xd3, 0xc8,
- 0xaa, 0x90, 0x6f, 0xdd, 0x94, 0x44, 0x8d, 0x15, 0xe5, 0xff, 0xfd, 0x80,
- 0xe3, 0xf9, 0x9b, 0xe3, 0x1e, 0xeb, 0x4f, 0xe9, 0x56, 0x9b, 0x11, 0x23,
- 0x3c, 0x67, 0x7f, 0xf4, 0xd0, 0xd9, 0xb3, 0xb2, 0x88, 0x91, 0xa2, 0x47,
- 0xbd, 0x2c, 0x59, 0xd7, 0x93, 0xd7, 0x3a, 0xf4, 0xb1, 0x65, 0x4c, 0x5d,
- 0xdf, 0xbb, 0x28, 0x89, 0x1a, 0x24, 0x8b, 0xff, 0xf9, 0xd3, 0xa8, 0xa9,
- 0xc7, 0x67, 0xfa, 0x72, 0x36, 0x3a, 0xe6, 0xcc, 0xe8, 0xb8, 0xc2, 0xbe,
- 0x19, 0xdf, 0xb3, 0x93, 0x62, 0xce, 0xb4, 0xce, 0x9a, 0x84, 0x43, 0xbb,
- 0xe7, 0x77, 0xff, 0x4d, 0x0d, 0x9b, 0x3b, 0x28, 0x89, 0x1a, 0x24, 0xab,
- 0xf7, 0x65, 0x11, 0x23, 0x45, 0xe3, 0x7e, 0xd6, 0xbf, 0x92, 0x3a, 0xff,
- 0x9b, 0x36, 0x76, 0x51, 0x12, 0x34, 0x49, 0xb6, 0x9b, 0x11, 0x3f, 0xd3,
- 0x38, 0x27, 0xb9, 0x8e, 0x1d, 0x7f, 0xfe, 0xd0, 0x63, 0x7c, 0xc5, 0x14,
- 0x86, 0xe6, 0xff, 0x3a, 0xf3, 0x23, 0xb1, 0xd7, 0x7a, 0x27, 0x5d, 0x3d,
- 0x33, 0xa2, 0x87, 0x05, 0xf4, 0xaf, 0xe4, 0x76, 0x9d, 0xb5, 0xca, 0xd8,
- 0xfd, 0xb4, 0xd8, 0x60, 0x46, 0x30, 0x91, 0xe5, 0x33, 0x18, 0x42, 0xcb,
- 0x39, 0x1d, 0x0f, 0xce, 0xc3, 0x0f, 0x0f, 0x30, 0xd6, 0xa7, 0x96, 0x6a,
- 0xf7, 0xb4, 0xa4, 0x56, 0xce, 0x35, 0x82, 0x5c, 0xbe, 0x5f, 0xaf, 0x82,
- 0x92, 0xd1, 0xa5, 0x78, 0x34, 0xfb, 0xd3, 0x6a, 0xd2, 0x91, 0xde, 0xaf,
- 0x28, 0x75, 0x9b, 0x4f, 0x33, 0xda, 0xf1, 0x89, 0x79, 0x90, 0x6e, 0xf2,
- 0x92, 0xa3, 0x16, 0xa4, 0xf7, 0xd9, 0xd9, 0xe9, 0xfa, 0x36, 0x11, 0xa6,
- 0xa8, 0x6a, 0xb2, 0xf9, 0xfd, 0xe0, 0xc2, 0x06, 0xd3, 0x46, 0x4e, 0xa5,
- 0x38, 0xb1, 0x2f, 0xf2, 0x7a, 0x58, 0x77, 0x9a, 0x41, 0x42, 0xaa, 0xd9,
- 0xd6, 0x80,
+ 0xfe, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x22, 0x5b, 0xbf, 0x01, 0xd7, 0xa4,
+ 0x2a, 0xe7, 0x5d, 0xbf, 0x8e, 0xbf, 0xfe, 0x8e, 0xc4, 0x85, 0xd4, 0xde,
+ 0x51, 0x9e, 0x3a, 0xe7, 0xd1, 0xd5, 0x23, 0xfa, 0x08, 0xba, 0x27, 0x5f,
+ 0xec, 0x64, 0x63, 0xdd, 0x43, 0xaf, 0xff, 0x68, 0x0b, 0xe8, 0xe6, 0xfe,
+ 0x17, 0xe9, 0xd7, 0x66, 0x8e, 0xbc, 0xee, 0xd3, 0x44, 0x5b, 0x52, 0x44,
+ 0x2e, 0x24, 0xb4, 0x56, 0xee, 0x68, 0xea, 0xe1, 0xe2, 0xe8, 0xbe, 0xff,
+ 0xfc, 0x07, 0xee, 0x0f, 0x39, 0x9b, 0xcb, 0xc8, 0xb3, 0xaf, 0x63, 0x60,
+ 0xeb, 0xf8, 0x23, 0x0d, 0x58, 0x0e, 0xbf, 0xe6, 0x45, 0x34, 0x83, 0xbc,
+ 0x8e, 0xbc, 0x14, 0x9c, 0xea, 0x43, 0xd4, 0x73, 0x8b, 0xff, 0x9b, 0xc8,
+ 0x52, 0x07, 0xca, 0xb2, 0xac, 0xac, 0x1d, 0x7f, 0x93, 0xa2, 0x07, 0x51,
+ 0xa7, 0x54, 0x22, 0x17, 0x14, 0xef, 0xff, 0x20, 0x8c, 0x6f, 0xf7, 0x39,
+ 0xac, 0x64, 0xeb, 0xb3, 0x72, 0xad, 0x05, 0x5b, 0xfe, 0x1a, 0x5f, 0xc5,
+ 0xaf, 0xf7, 0xb3, 0x9f, 0xad, 0x34, 0x53, 0x06, 0xa6, 0xfe, 0x97, 0x53,
+ 0x66, 0x4c, 0x75, 0x41, 0xf9, 0xba, 0x25, 0xfd, 0xd4, 0x6c, 0x2d, 0x0e,
+ 0xbf, 0xd1, 0xfc, 0xef, 0x28, 0x57, 0x3a, 0xc3, 0x07, 0xc2, 0x25, 0x76,
+ 0x61, 0x58, 0x5d, 0x5f, 0x55, 0xc2, 0xf1, 0x09, 0x89, 0xcb, 0xb2, 0x1f,
+ 0x6a, 0x11, 0x35, 0x51, 0x06, 0xbb, 0x08, 0x01, 0x85, 0x2e, 0x88, 0x76,
+ 0xe3, 0x0b, 0xfb, 0x08, 0x1b, 0xff, 0xff, 0x9d, 0x6c, 0x27, 0x38, 0x0e,
+ 0x72, 0x07, 0x14, 0x4e, 0xf7, 0x3e, 0x9d, 0x7f, 0xf9, 0x56, 0x51, 0x95,
+ 0x79, 0xc2, 0xaa, 0xf9, 0xf3, 0xbb, 0x67, 0x5f, 0xb8, 0xd7, 0x76, 0x9a,
+ 0x2a, 0x2b, 0xf4, 0x77, 0x39, 0x87, 0x5f, 0xff, 0xbf, 0x94, 0xea, 0xb4,
+ 0x2b, 0x73, 0xb7, 0x9f, 0x3e, 0x77, 0x6c, 0xeb, 0xff, 0xf3, 0xc8, 0x63,
+ 0x59, 0xbb, 0x45, 0xf3, 0x76, 0x9d, 0x66, 0x24, 0x9b, 0xc6, 0x31, 0x34,
+ 0xcf, 0xa4, 0xbb, 0x1a, 0xef, 0xfc, 0x1c, 0x5b, 0x1b, 0x78, 0x29, 0xe3,
+ 0xaf, 0x63, 0x38, 0x75, 0xfe, 0xcc, 0x9c, 0x31, 0x81, 0x3a, 0xf7, 0x60,
+ 0x27, 0x5f, 0xe8, 0x84, 0x11, 0x02, 0xb9, 0xd7, 0x38, 0x0e, 0xbe, 0xea,
+ 0x75, 0x85, 0x42, 0x2b, 0x94, 0x1b, 0x98, 0xc7, 0xa3, 0x6c, 0x99, 0x5f,
+ 0xb8, 0xd7, 0x76, 0x9a, 0x2b, 0xdb, 0xf2, 0x6d, 0x34, 0x13, 0x9d, 0x74,
+ 0x48, 0xeb, 0xa3, 0xf3, 0xac, 0xc6, 0x22, 0x27, 0x86, 0x6e, 0x57, 0xf8,
+ 0xad, 0xff, 0xcc, 0x3c, 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x89, 0x1a, 0xff,
+ 0xf3, 0x0b, 0x79, 0x31, 0x9c, 0x6b, 0xbb, 0x4d, 0x13, 0xc5, 0xff, 0xe6,
+ 0x16, 0xf2, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x27, 0xfb, 0xff, 0xcc, 0x2d,
+ 0xe4, 0xc6, 0x71, 0xae, 0xed, 0x34, 0x50, 0xd7, 0xff, 0x2d, 0xe4, 0xc6,
+ 0x71, 0xae, 0xed, 0x34, 0x51, 0x17, 0xfe, 0x93, 0x00, 0xd7, 0xc8, 0xd4,
+ 0x48, 0xea, 0x61, 0x12, 0x30, 0xa1, 0x7f, 0xe9, 0x93, 0xbb, 0xe7, 0x83,
+ 0x8b, 0x3a, 0xff, 0xc2, 0xec, 0x78, 0x40, 0xf2, 0xd1, 0xd7, 0xee, 0x35,
+ 0xdd, 0xa6, 0x8a, 0x46, 0xff, 0xa2, 0x51, 0xc9, 0xe3, 0x93, 0x9d, 0x79,
+ 0xe4, 0xc6, 0x1f, 0x60, 0x99, 0xdf, 0xd2, 0xce, 0xf5, 0xe4, 0x75, 0xff,
+ 0xfd, 0x81, 0xec, 0x7d, 0x63, 0xc2, 0xff, 0xeb, 0x51, 0xf9, 0x56, 0x62,
+ 0x13, 0xa4, 0x69, 0xfa, 0xe1, 0x53, 0xe3, 0x2d, 0xb2, 0xcb, 0xf7, 0x1a,
+ 0xee, 0xd3, 0x44, 0xa1, 0x7f, 0xf8, 0x5f, 0xda, 0xfa, 0x20, 0x90, 0xe2,
+ 0xce, 0xbe, 0x61, 0xe4, 0xc6, 0x1f, 0xe2, 0xcc, 0xea, 0x76, 0x7d, 0x2c,
+ 0xa7, 0x67, 0x83, 0x0e, 0x96, 0xc7, 0xd6, 0x8a, 0x6a, 0xf0, 0xee, 0xe4,
+ 0x3c, 0x96, 0x87, 0xd5, 0x1f, 0xd5, 0xd5, 0x2a, 0xfa, 0x87, 0x40, 0x23,
+ 0xc7, 0xda, 0x86, 0xad, 0xff, 0xe6, 0x16, 0xf2, 0x63, 0x38, 0xd7, 0x76,
+ 0x9a, 0x27, 0x3b, 0xff, 0xcc, 0x2d, 0xe4, 0xc6, 0x71, 0xae, 0xed, 0x34,
+ 0x51, 0x37, 0xf2, 0x6a, 0x69, 0x27, 0xe7, 0x5f, 0xe8, 0x9f, 0xee, 0xdb,
+ 0x8f, 0xe7, 0x5e, 0xe4, 0x98, 0xe9, 0xf3, 0x7d, 0x2e, 0xae, 0x26, 0x97,
+ 0xa5, 0x70, 0x42, 0xf6, 0xfd, 0xc6, 0xbb, 0xb4, 0xd1, 0x0e, 0x5f, 0xc0,
+ 0x6f, 0x12, 0x04, 0xeb, 0x31, 0x87, 0xbd, 0xd3, 0x3b, 0xfe, 0x8e, 0x63,
+ 0x7b, 0x1b, 0xc8, 0xeb, 0xe6, 0xbb, 0xb4, 0xd1, 0x17, 0xdf, 0xb2, 0x69,
+ 0x3e, 0x8e, 0xae, 0x1e, 0xa7, 0xd2, 0xdb, 0xfd, 0xac, 0x0f, 0x73, 0xf7,
+ 0x3a, 0xe1, 0x9c, 0xeb, 0xfe, 0xf0, 0xc2, 0xfe, 0x87, 0xb0, 0x75, 0x41,
+ 0xe7, 0xa0, 0xb5, 0xda, 0xdc, 0xeb, 0xef, 0x4a, 0x14, 0x2a, 0x96, 0x6e,
+ 0x5c, 0x5e, 0xfc, 0xf3, 0xfb, 0x3a, 0x75, 0x98, 0x9d, 0x3d, 0x1c, 0x84,
+ 0x64, 0xc4, 0x9d, 0x84, 0x08, 0xac, 0xed, 0x90, 0x5f, 0xff, 0xff, 0x0b,
+ 0xb1, 0x80, 0x54, 0xa2, 0x89, 0xee, 0xe2, 0x4b, 0x5f, 0x31, 0x48, 0x91,
+ 0xd7, 0xfe, 0x79, 0x31, 0x9c, 0x6b, 0xbb, 0x4d, 0x13, 0x25, 0x98, 0x6a,
+ 0x33, 0x17, 0x08, 0x2b, 0xba, 0xb3, 0xaf, 0xdc, 0x6b, 0xbb, 0x4d, 0x16,
+ 0xf5, 0x98, 0x09, 0xe4, 0xe0, 0xb5, 0xff, 0xe6, 0x16, 0xf2, 0x63, 0x38,
+ 0xd7, 0x76, 0x9a, 0x29, 0x3b, 0x95, 0x95, 0x6c, 0xeb, 0xfb, 0x3c, 0x31,
+ 0x0b, 0x3a, 0xfe, 0xdf, 0xff, 0xbc, 0x7f, 0xce, 0xbb, 0xac, 0x2a, 0x0f,
+ 0xf3, 0xa4, 0x0e, 0x55, 0x50, 0xb9, 0xc7, 0x28, 0xfe, 0x72, 0x33, 0x8d,
+ 0x3c, 0x6c, 0x28, 0xfb, 0x0d, 0x3b, 0xfc, 0xc6, 0x71, 0xae, 0xed, 0x34,
+ 0x43, 0xb7, 0xee, 0x35, 0xdd, 0xa6, 0x89, 0x62, 0xfb, 0x3f, 0x5a, 0x1d,
+ 0x7e, 0x61, 0x6f, 0x26, 0x30, 0xf5, 0x36, 0xcc, 0xef, 0xf3, 0x19, 0xc6,
+ 0xbb, 0xb4, 0xd1, 0x18, 0x5f, 0x31, 0x2c, 0xd1, 0xd7, 0xff, 0xfd, 0x2d,
+ 0x30, 0xde, 0xbc, 0xcd, 0xee, 0x71, 0x58, 0xec, 0xcb, 0xd1, 0xd7, 0xec,
+ 0xf7, 0xf0, 0xd3, 0xaf, 0xff, 0x47, 0x93, 0xf8, 0x90, 0x7b, 0x02, 0xd3,
+ 0xaf, 0xdc, 0x6b, 0xbb, 0x4d, 0x11, 0xed, 0xf6, 0x9f, 0x7d, 0x87, 0x5d,
+ 0x26, 0x30, 0xf5, 0xfc, 0x67, 0x7f, 0xff, 0x3b, 0x02, 0x0c, 0xee, 0x0f,
+ 0xf8, 0x3e, 0xee, 0x1d, 0x66, 0x37, 0x4e, 0xf2, 0x67, 0x0e, 0x13, 0xbc,
+ 0x27, 0xc4, 0xba, 0xfd, 0xc6, 0xbb, 0xb4, 0xd1, 0x61, 0xdf, 0xe9, 0x0c,
+ 0x66, 0xb0, 0x4e, 0xb3, 0x18, 0x7c, 0x5b, 0x99, 0xdf, 0xe6, 0x33, 0x8d,
+ 0x77, 0x69, 0xa2, 0xe7, 0xbf, 0xff, 0xff, 0xfa, 0x15, 0xa4, 0xa7, 0x6f,
+ 0x7e, 0x7c, 0xee, 0xdb, 0x13, 0x81, 0x45, 0x5d, 0x0a, 0x8d, 0xe7, 0x9d,
+ 0xab, 0xf9, 0xf3, 0xbb, 0x67, 0x54, 0x2e, 0x6e, 0xcf, 0x09, 0x39, 0x21,
+ 0xb4, 0xfd, 0x23, 0xde, 0x5c, 0x2e, 0x7c, 0x53, 0xb4, 0x7f, 0x7f, 0x98,
+ 0xce, 0x35, 0xdd, 0xa6, 0x88, 0x7a, 0xf9, 0xae, 0xed, 0x34, 0x44, 0xd7,
+ 0xf6, 0x6d, 0x01, 0x78, 0x13, 0xaf, 0xf7, 0x80, 0xfb, 0xf6, 0x36, 0x1d,
+ 0x5c, 0x44, 0x88, 0x96, 0xf8, 0xbe, 0xfe, 0x4f, 0xf5, 0xf3, 0x02, 0x75,
+ 0xff, 0xfa, 0x39, 0xff, 0x63, 0x64, 0xd1, 0x0b, 0xd6, 0x04, 0xeb, 0xfe,
+ 0xef, 0x63, 0x64, 0xb3, 0x90, 0x75, 0xbd, 0xd4, 0x48, 0x3a, 0xbd, 0xff,
+ 0x27, 0x93, 0xd9, 0xfc, 0x70, 0xea, 0xc3, 0xdf, 0x72, 0x8b, 0xff, 0xfb,
+ 0xdd, 0x8e, 0x7f, 0xac, 0x0f, 0x80, 0xed, 0xce, 0x1d, 0x77, 0x96, 0x75,
+ 0xff, 0xec, 0xef, 0xd9, 0xf5, 0x09, 0xbf, 0xa1, 0x67, 0x5f, 0xfa, 0x78,
+ 0x97, 0xdc, 0xe6, 0xb1, 0x93, 0xab, 0x11, 0xfd, 0xba, 0xdf, 0x45, 0x80,
+ 0x99, 0x7d, 0xe0, 0x3f, 0xd3, 0x44, 0x2f, 0x7e, 0xee, 0x4e, 0x01, 0x3a,
+ 0xf9, 0xf9, 0x1b, 0x0e, 0xa0, 0x9e, 0x4f, 0xe4, 0xf6, 0x63, 0x15, 0xa2,
+ 0x70, 0xbf, 0xb1, 0x8f, 0x6a, 0x31, 0xe0, 0x1e, 0xec, 0x79, 0xbf, 0xf7,
+ 0x01, 0x3e, 0x76, 0x61, 0x80, 0x9d, 0x77, 0x5c, 0xeb, 0x00, 0xea, 0xc3,
+ 0x4b, 0xa1, 0x5b, 0xdf, 0xe9, 0x88, 0x44, 0x27, 0x99, 0x2f, 0xff, 0xb1,
+ 0x25, 0xa6, 0x33, 0x79, 0x3c, 0xff, 0x5a, 0x75, 0x42, 0x22, 0x7a, 0x6d,
+ 0x7e, 0x56, 0x34, 0x93, 0xaa, 0x0e, 0xbf, 0x95, 0x9f, 0xbd, 0xee, 0x4e,
+ 0x75, 0xba, 0x75, 0x2b, 0x27, 0x8a, 0x03, 0x5b, 0xe0, 0xe0, 0xcc, 0x75,
+ 0xc9, 0xe3, 0xad, 0xe4, 0x36, 0xdd, 0x21, 0xbf, 0xdb, 0xfb, 0x79, 0x00,
+ 0x54, 0x3a, 0xff, 0xd1, 0x30, 0xe6, 0xc7, 0x5a, 0xd0, 0xea, 0x73, 0xf4,
+ 0x01, 0xb5, 0xff, 0xff, 0xdd, 0x00, 0x53, 0x39, 0x30, 0xe6, 0xce, 0xe0,
+ 0x63, 0x5a, 0x85, 0x0e, 0xbf, 0xfc, 0x93, 0x4b, 0x37, 0x97, 0xc5, 0xbb,
+ 0x89, 0xd7, 0x3e, 0xd1, 0xd6, 0x54, 0x62, 0x72, 0x2a, 0x42, 0x69, 0xa4,
+ 0x3d, 0x73, 0x74, 0xbb, 0xb6, 0xd4, 0x3a, 0xfd, 0xd7, 0xf3, 0xc8, 0xeb,
+ 0xf9, 0x38, 0x39, 0x9c, 0x3a, 0xff, 0x4b, 0x51, 0xa5, 0x6a, 0xac, 0xab,
+ 0x27, 0x5f, 0xfc, 0xbf, 0x9a, 0x1c, 0xde, 0x42, 0xf3, 0x9d, 0x7b, 0x49,
+ 0xf9, 0xd5, 0x87, 0xc4, 0x88, 0xd7, 0x99, 0x65, 0x92, 0xaf, 0xce, 0x3e,
+ 0xee, 0x14, 0xc1, 0x7f, 0x7e, 0x7f, 0x4d, 0x9e, 0x3a, 0x82, 0x89, 0xbf,
+ 0xcf, 0xc4, 0xd6, 0xfd, 0xd1, 0x55, 0xfb, 0x7b, 0x47, 0x5c, 0xee, 0x75,
+ 0xba, 0x87, 0x8e, 0xe6, 0x77, 0xff, 0x7e, 0x93, 0x7c, 0xec, 0x27, 0x00,
+ 0xae, 0x75, 0xfc, 0x20, 0xf2, 0x4f, 0x07, 0x5f, 0xf9, 0x14, 0x81, 0x8d,
+ 0x42, 0x2c, 0xeb, 0xfb, 0x36, 0x02, 0x59, 0xa3, 0xaf, 0xb0, 0x39, 0x39,
+ 0xd7, 0xca, 0xff, 0x21, 0x58, 0x3a, 0xee, 0x41, 0xd5, 0x8a, 0xdb, 0x5a,
+ 0x4d, 0xb9, 0x52, 0x46, 0x80, 0xae, 0xef, 0x31, 0x32, 0xd2, 0xba, 0x58,
+ 0x27, 0x7e, 0x2e, 0xd8, 0x43, 0xb4, 0x57, 0x7e, 0x66, 0x30, 0x28, 0x75,
+ 0xe0, 0x7b, 0x47, 0x5f, 0xff, 0xff, 0xf6, 0xbe, 0x77, 0x27, 0x86, 0x77,
+ 0x96, 0xbe, 0x01, 0xbc, 0xe4, 0x7c, 0x99, 0x4d, 0xfe, 0x7c, 0xee, 0xd9,
+ 0xd5, 0x88, 0xec, 0x69, 0x37, 0x87, 0x2e, 0x07, 0xe7, 0x5d, 0xb6, 0xac,
+ 0x9d, 0x7b, 0xe4, 0x9a, 0x75, 0x41, 0xe9, 0xa8, 0x2e, 0xb1, 0xeb, 0xff,
+ 0xfb, 0x9f, 0x07, 0x36, 0x67, 0x25, 0xf2, 0x02, 0xf3, 0x68, 0xeb, 0xff,
+ 0xff, 0x87, 0x78, 0x50, 0x70, 0x3d, 0x49, 0xbe, 0x6b, 0x37, 0x97, 0x31,
+ 0x93, 0xab, 0x11, 0xac, 0x2c, 0x17, 0xde, 0x04, 0x4e, 0x75, 0xfe, 0x96,
+ 0x77, 0x17, 0x0d, 0x3a, 0x90, 0xf4, 0xfc, 0x45, 0x7f, 0xff, 0x6f, 0x2d,
+ 0x2f, 0x07, 0xe6, 0xd2, 0x76, 0x74, 0xce, 0x1d, 0x65, 0x73, 0xab, 0x0f,
+ 0xcd, 0xac, 0x17, 0xff, 0xfe, 0x67, 0xe0, 0xe3, 0x7a, 0x83, 0x80, 0xdf,
+ 0xdf, 0x1d, 0x9c, 0x50, 0xeb, 0xfc, 0xa0, 0x41, 0x1d, 0x18, 0x3a, 0xff,
+ 0x6f, 0x2d, 0x28, 0x08, 0xdc, 0xeb, 0xfc, 0xec, 0x82, 0x68, 0xf3, 0x9d,
+ 0x50, 0x98, 0x66, 0x38, 0xa1, 0x90, 0x9b, 0x5f, 0xfa, 0x34, 0x39, 0xb3,
+ 0xe4, 0x97, 0x23, 0xaf, 0xbf, 0xf2, 0x4e, 0x75, 0xfe, 0xf7, 0x50, 0x7f,
+ 0xfa, 0xb3, 0xaf, 0xf4, 0xf0, 0xb1, 0x8d, 0xff, 0x3a, 0xd1, 0x23, 0xe9,
+ 0x73, 0x5b, 0xff, 0x9f, 0x92, 0xf9, 0xe1, 0x89, 0x67, 0x8e, 0xa8, 0x57,
+ 0x4d, 0x8e, 0x89, 0x09, 0x4e, 0x46, 0x5b, 0xd3, 0xa7, 0x41, 0x18, 0x46,
+ 0x00, 0x9a, 0xff, 0xfb, 0x88, 0x05, 0x4c, 0x7c, 0xd0, 0x3f, 0x5e, 0x78,
+ 0xeb, 0x81, 0x23, 0xaf, 0xd1, 0xfe, 0xa7, 0xf1, 0xd7, 0x9f, 0xda, 0x3a,
+ 0xe0, 0x4e, 0x75, 0xe1, 0xf4, 0xd2, 0x36, 0x5c, 0x1b, 0xbf, 0x80, 0xdf,
+ 0x81, 0xdd, 0x93, 0xaa, 0x0f, 0x95, 0x0c, 0xef, 0xf7, 0x20, 0x31, 0xd8,
+ 0x91, 0xd7, 0xff, 0xd1, 0xef, 0x82, 0x0d, 0xaf, 0x99, 0xed, 0xbc, 0xf1,
+ 0xd4, 0x88, 0x89, 0x01, 0x8d, 0xff, 0xdd, 0x85, 0x3e, 0x78, 0x5f, 0xd1,
+ 0xe3, 0xaf, 0xf7, 0xcd, 0xe4, 0x9d, 0x02, 0xce, 0xaf, 0xcf, 0xec, 0x51,
+ 0x6f, 0xfe, 0xcd, 0x98, 0x1f, 0x9e, 0x51, 0x19, 0xd1, 0xd7, 0xfe, 0xe4,
+ 0xdf, 0x35, 0x09, 0x3b, 0xf8, 0xea, 0x84, 0x56, 0x04, 0x88, 0x09, 0x37,
+ 0x3f, 0xe7, 0x5f, 0xff, 0x7c, 0x18, 0xd4, 0x4e, 0x38, 0x1e, 0xa4, 0xc7,
+ 0x5f, 0xff, 0xfd, 0xae, 0x0c, 0x4d, 0xf3, 0xef, 0x92, 0x59, 0xbf, 0xb3,
+ 0x60, 0xe6, 0x8e, 0xae, 0x23, 0x1c, 0x54, 0x2b, 0xc8, 0xff, 0x04, 0x37,
+ 0x68, 0xeb, 0xa6, 0x91, 0xd5, 0x06, 0x87, 0x81, 0x57, 0xff, 0x0f, 0xb5,
+ 0xb1, 0x3d, 0x18, 0x33, 0x1d, 0x7e, 0xe2, 0x6a, 0x37, 0x3a, 0xb0, 0xfa,
+ 0xdd, 0x12, 0xff, 0x4e, 0xa8, 0x9a, 0x49, 0xed, 0x1d, 0x7e, 0x1f, 0x77,
+ 0x36, 0x8e, 0xbf, 0x4d, 0xa7, 0xe2, 0x87, 0x5e, 0x76, 0x79, 0x07, 0xa5,
+ 0x85, 0x35, 0x24, 0x6e, 0xa1, 0x07, 0x21, 0x17, 0x7f, 0xdd, 0x4e, 0x4d,
+ 0xd7, 0xce, 0x1d, 0x7f, 0xff, 0xff, 0x7f, 0xa1, 0xc7, 0xdf, 0xe0, 0x7a,
+ 0x0f, 0x83, 0x9b, 0xcb, 0x01, 0x38, 0xe3, 0xee, 0x75, 0x35, 0x18, 0xc8,
+ 0x71, 0x79, 0xdd, 0xa6, 0x8a, 0x62, 0xb0, 0xf2, 0x5a, 0x45, 0x7f, 0xec,
+ 0x1d, 0xe5, 0xaf, 0x47, 0x26, 0x3a, 0xf6, 0x27, 0xe7, 0x5b, 0x0e, 0xbd,
+ 0xb8, 0xe7, 0xe6, 0xab, 0x60, 0xdd, 0x22, 0x27, 0x9d, 0xa6, 0xff, 0x73,
+ 0xaf, 0xf1, 0x61, 0x98, 0xeb, 0xfd, 0xf3, 0x79, 0x0c, 0x66, 0x8e, 0xa4,
+ 0x3e, 0xa7, 0x36, 0xbf, 0xff, 0x7e, 0x9a, 0xf9, 0xd7, 0xd7, 0xa2, 0x6d,
+ 0x77, 0x0e, 0xbf, 0x93, 0xae, 0x93, 0xc1, 0xd7, 0xa5, 0x1b, 0x9d, 0x7f,
+ 0x96, 0x1e, 0xc4, 0xf8, 0xc9, 0xd5, 0x87, 0xf7, 0xb9, 0x5b, 0x8e, 0x5f,
+ 0xff, 0xe1, 0xc6, 0xfb, 0xd1, 0xed, 0x4c, 0x38, 0xcf, 0xc8, 0x56, 0x0e,
+ 0xbf, 0xf3, 0x61, 0x7d, 0xcd, 0x62, 0x09, 0xd5, 0x08, 0xa2, 0xeb, 0x3d,
+ 0xfb, 0x91, 0xb2, 0x38, 0x75, 0xfc, 0xe3, 0xf0, 0x30, 0x27, 0x56, 0x1f,
+ 0xb2, 0x11, 0x00, 0xa2, 0xa1, 0x95, 0xe1, 0x3a, 0xb4, 0x85, 0x83, 0x0c,
+ 0x05, 0x21, 0x52, 0xd8, 0xd2, 0x77, 0x8c, 0xb9, 0x12, 0x66, 0x8d, 0xa3,
+ 0x91, 0xa1, 0xae, 0x17, 0xfd, 0x84, 0x5f, 0xe4, 0x03, 0x0d, 0x3f, 0x46,
+ 0x8d, 0x7f, 0xdc, 0x76, 0x7e, 0x38, 0x5e, 0x73, 0xaf, 0xe7, 0x66, 0x61,
+ 0x40, 0x9d, 0x7f, 0xff, 0x83, 0x93, 0xb8, 0xfb, 0x50, 0xdf, 0x8b, 0x5a,
+ 0x0b, 0x4e, 0xbf, 0x83, 0xa7, 0x8d, 0xe4, 0x75, 0x42, 0x23, 0x9d, 0x86,
+ 0xff, 0xa2, 0x6e, 0xa4, 0x2d, 0xc2, 0x75, 0x28, 0x9a, 0x77, 0x0e, 0xc6,
+ 0x17, 0x60, 0x21, 0xbe, 0xc1, 0x51, 0x5c, 0xeb, 0xff, 0xff, 0xf7, 0x53,
+ 0xdd, 0xce, 0x46, 0xcf, 0x8b, 0x06, 0xd7, 0xcc, 0xde, 0x58, 0x01, 0xff,
+ 0x47, 0x5b, 0xc8, 0x8b, 0x1d, 0x12, 0x5f, 0xfa, 0x1b, 0xf0, 0x5f, 0x4b,
+ 0x81, 0x3a, 0xff, 0xfd, 0x99, 0xd4, 0x6f, 0x73, 0xe6, 0x81, 0xd8, 0x57,
+ 0x3a, 0xff, 0xfb, 0xdd, 0xcf, 0xfe, 0x2e, 0x33, 0xc1, 0xc1, 0x3a, 0xfe,
+ 0x70, 0xf3, 0x80, 0x9c, 0xeb, 0xf4, 0x60, 0xfb, 0x6c, 0xea, 0x69, 0xeb,
+ 0x2c, 0xba, 0xfb, 0xc9, 0xcc, 0x3a, 0xdb, 0xfc, 0x3c, 0x2c, 0x22, 0xb6,
+ 0xb1, 0x31, 0x27, 0x87, 0x45, 0x2d, 0x3d, 0x41, 0x3d, 0xf4, 0x6d, 0x57,
+ 0xff, 0xff, 0xe1, 0xcd, 0xe4, 0x9a, 0x1c, 0xd9, 0xdc, 0x9b, 0xb0, 0x33,
+ 0x7c, 0x76, 0xa6, 0xc3, 0xa9, 0x11, 0x7a, 0x03, 0x6b, 0xff, 0xc8, 0x1f,
+ 0x8b, 0x4f, 0x90, 0x17, 0x9b, 0x47, 0x5d, 0x29, 0x1d, 0x6e, 0x41, 0xf1,
+ 0xce, 0x9b, 0x7e, 0x94, 0x6f, 0x2d, 0x1d, 0x7f, 0xff, 0xff, 0xec, 0x15,
+ 0x3e, 0x27, 0x40, 0xc4, 0xc9, 0xe8, 0x58, 0xba, 0x9d, 0x46, 0x33, 0xbb,
+ 0xff, 0x01, 0x2a, 0xff, 0xff, 0xe6, 0xa3, 0x21, 0x07, 0x3e, 0x02, 0x27,
+ 0xd3, 0x7a, 0x0e, 0xee, 0xec, 0x9d, 0x70, 0x27, 0xdd, 0x34, 0x04, 0x28,
+ 0xd4, 0x27, 0xea, 0x17, 0x3a, 0x7b, 0x2a, 0xe5, 0xe1, 0x0a, 0x31, 0xb4,
+ 0x5f, 0xe7, 0x96, 0x2d, 0xc7, 0xf3, 0xaf, 0xb3, 0xb1, 0x31, 0xd7, 0x96,
+ 0xdf, 0x9d, 0x3d, 0x27, 0x31, 0xbf, 0xff, 0xfd, 0xc6, 0x8e, 0x6c, 0xf9,
+ 0xa4, 0xc1, 0xff, 0xe0, 0xe6, 0xc1, 0xcd, 0x6c, 0x3a, 0xff, 0x9b, 0x8e,
+ 0xbf, 0x9b, 0x70, 0xb3, 0xab, 0x11, 0x75, 0xc7, 0xeb, 0xff, 0xf2, 0x0f,
+ 0xbb, 0x9b, 0x5e, 0x9b, 0x15, 0xdc, 0x7f, 0x3a, 0xfd, 0x0c, 0xfc, 0xd4,
+ 0xc7, 0x5f, 0xf8, 0x67, 0x1c, 0xd9, 0xa0, 0x46, 0xe7, 0x5f, 0xf8, 0x3d,
+ 0x8d, 0xfe, 0x2a, 0xfd, 0x9f, 0xa1, 0xd5, 0x08, 0x8a, 0x9d, 0x02, 0x91,
+ 0x35, 0x4d, 0x11, 0x79, 0x68, 0x10, 0xb5, 0xbf, 0xf0, 0xc9, 0xbd, 0x4e,
+ 0x88, 0x27, 0x3a, 0xf7, 0xb1, 0x52, 0x75, 0x41, 0xee, 0xe1, 0xf5, 0xed,
+ 0xbc, 0xe9, 0xd7, 0x60, 0x4e, 0xa9, 0xd5, 0x9a, 0xca, 0x52, 0x1e, 0xa1,
+ 0x3f, 0xe2, 0x0d, 0x83, 0xd7, 0xe4, 0xf6, 0xb3, 0xf3, 0xaf, 0xdd, 0xcd,
+ 0x89, 0xb0, 0xeb, 0xc9, 0x9f, 0x9d, 0x7f, 0x06, 0x07, 0xaf, 0x23, 0xaf,
+ 0x40, 0x60, 0xeb, 0xf6, 0x7b, 0x4f, 0x37, 0xc3, 0xc5, 0x59, 0x5d, 0xfc,
+ 0xcf, 0xc5, 0x6d, 0x5a, 0xaa, 0x95, 0xb3, 0xaa, 0x48, 0x86, 0x44, 0x1b,
+ 0xff, 0xf7, 0x01, 0xce, 0x40, 0xe2, 0x89, 0xde, 0xe7, 0xd3, 0xaf, 0x80,
+ 0xfb, 0xf8, 0xea, 0x92, 0x7a, 0x21, 0x27, 0x50, 0xaa, 0x68, 0x73, 0x70,
+ 0x8b, 0xaa, 0xd4, 0x75, 0xfd, 0xa6, 0xb5, 0xc5, 0x43, 0xa9, 0x56, 0x36,
+ 0xfe, 0x0a, 0xbf, 0xc3, 0xf3, 0x66, 0xf2, 0xd4, 0xc7, 0x5d, 0x3e, 0xe7,
+ 0x5f, 0xba, 0xea, 0xf1, 0xf9, 0xd4, 0x13, 0xfb, 0x73, 0x9d, 0xa1, 0x8b,
+ 0xfd, 0xc9, 0x87, 0x3a, 0xfe, 0x3a, 0xa1, 0x30, 0x4c, 0x85, 0x0a, 0x18,
+ 0xdf, 0x93, 0x81, 0xc1, 0x3a, 0xfd, 0xfe, 0x7b, 0xec, 0xe7, 0x5f, 0xe6,
+ 0x7d, 0x9d, 0xf9, 0xbe, 0x8e, 0xa8, 0x3e, 0x27, 0x2b, 0xa9, 0x23, 0x6b,
+ 0xa6, 0x63, 0x08, 0x7b, 0xfe, 0xf7, 0x72, 0x4e, 0x39, 0xb9, 0xd7, 0xff,
+ 0xfc, 0x2f, 0xfe, 0xa7, 0xc4, 0x1f, 0x0e, 0x6c, 0xf9, 0xa6, 0x44, 0xea,
+ 0x14, 0x50, 0x78, 0xde, 0xff, 0xc9, 0x93, 0x7c, 0xd4, 0x75, 0xd5, 0xce,
+ 0xbf, 0xed, 0xf2, 0x37, 0x98, 0x61, 0x67, 0x5f, 0xdb, 0xeb, 0xb8, 0xfc,
+ 0x3a, 0xff, 0xff, 0xc8, 0xbe, 0x26, 0x6e, 0x20, 0xf4, 0x77, 0xe6, 0xc4,
+ 0xf4, 0xd0, 0x75, 0x3a, 0x27, 0x3c, 0x5b, 0x41, 0x4c, 0xe7, 0xa8, 0x5e,
+ 0x86, 0xad, 0xff, 0x67, 0x27, 0x84, 0xe6, 0x09, 0xd6, 0x59, 0xdf, 0x0d,
+ 0xb5, 0xe1, 0xc0, 0x9d, 0x50, 0x6f, 0x37, 0x22, 0xbf, 0xb7, 0xd6, 0x60,
+ 0xa8, 0x75, 0xf2, 0xfe, 0xc7, 0xe7, 0x5f, 0xfe, 0x9c, 0x3c, 0x76, 0x8e,
+ 0x6c, 0xe2, 0x68, 0xea, 0xc4, 0x4e, 0x21, 0x68, 0x09, 0x2f, 0xf3, 0xfb,
+ 0xaf, 0x37, 0xd5, 0x9d, 0x78, 0x1b, 0xfe, 0x75, 0x42, 0xb4, 0x1c, 0x8d,
+ 0x6d, 0x21, 0x51, 0xc8, 0x5e, 0xb9, 0x70, 0x9a, 0xdf, 0xde, 0x7e, 0xfc,
+ 0x0c, 0x1d, 0x7f, 0xfb, 0xda, 0xfb, 0xaf, 0x9e, 0x18, 0x96, 0x78, 0xeb,
+ 0xfd, 0xe4, 0x9f, 0x3a, 0x0f, 0x1d, 0x69, 0x8e, 0xbf, 0xb0, 0x19, 0xd6,
+ 0xce, 0x75, 0xd9, 0xbc, 0x1b, 0xed, 0x08, 0xdf, 0xdd, 0x79, 0x2f, 0x88,
+ 0x75, 0xff, 0xca, 0x28, 0xfe, 0xd7, 0x86, 0x37, 0x91, 0xd7, 0xf7, 0x86,
+ 0x25, 0x9e, 0x3a, 0xa0, 0xfc, 0x64, 0x8d, 0x72, 0x68, 0xeb, 0xdc, 0xcd,
+ 0xce, 0xa0, 0x9b, 0x1f, 0xc5, 0x6f, 0xff, 0x3a, 0x9e, 0x52, 0x06, 0x59,
+ 0xd4, 0x59, 0xd7, 0xe4, 0xd6, 0xa1, 0x67, 0x52, 0x22, 0x44, 0x48, 0xb6,
+ 0x24, 0xd4, 0x2a, 0xc8, 0xc2, 0xe5, 0x13, 0x51, 0xc7, 0xf2, 0xc1, 0x84,
+ 0xe8, 0x21, 0xc7, 0x7e, 0x0a, 0x0b, 0x84, 0xeb, 0xff, 0xf4, 0xbb, 0x93,
+ 0x76, 0x05, 0x41, 0xcf, 0x74, 0x07, 0x52, 0x1f, 0xd7, 0x09, 0x6f, 0xff,
+ 0xf2, 0x66, 0xf2, 0xd7, 0xbb, 0x0b, 0x84, 0x0f, 0xc8, 0x56, 0x0e, 0xbf,
+ 0xce, 0x3f, 0x1b, 0xaf, 0xc2, 0x75, 0xff, 0x81, 0xaf, 0x8b, 0xfb, 0xd7,
+ 0xec, 0x1d, 0x7e, 0xcf, 0x03, 0x37, 0x3a, 0xf2, 0x99, 0xb9, 0xd7, 0x44,
+ 0xdf, 0x0f, 0x13, 0xc4, 0xf4, 0x28, 0xb6, 0x04, 0x21, 0xaf, 0xff, 0xff,
+ 0xc0, 0x1f, 0x8c, 0xbe, 0xf2, 0xe3, 0xff, 0xf3, 0x40, 0x8d, 0xfb, 0x88,
+ 0x38, 0xa1, 0xd7, 0xff, 0xe0, 0x73, 0x99, 0xed, 0x75, 0x33, 0xe7, 0x7f,
+ 0x83, 0xab, 0x11, 0xc1, 0xd8, 0x44, 0xdf, 0xb0, 0x5b, 0xf5, 0x67, 0x5f,
+ 0xfd, 0xdc, 0x81, 0x98, 0x73, 0xda, 0x73, 0xad, 0x2f, 0x1f, 0x4e, 0xd1,
+ 0x45, 0xff, 0xf8, 0x38, 0xbf, 0x9b, 0x5e, 0x8d, 0x4d, 0x27, 0xe4, 0xe7,
+ 0x5f, 0xff, 0xde, 0x49, 0xf0, 0x3f, 0x16, 0xf2, 0xe2, 0x4e, 0xeb, 0x3a,
+ 0xff, 0x4e, 0xeb, 0x18, 0xe4, 0xc7, 0x5f, 0xf6, 0xf8, 0xa7, 0xeb, 0xcf,
+ 0x9c, 0xc4, 0x48, 0x22, 0xed, 0xff, 0x60, 0xcf, 0xf3, 0xf7, 0x79, 0x8e,
+ 0xbf, 0xee, 0x4f, 0x13, 0xce, 0x0e, 0x4e, 0x75, 0xff, 0xbe, 0x4d, 0xd0,
+ 0x28, 0x98, 0x2a, 0x1d, 0x7f, 0x87, 0xe6, 0x81, 0xb6, 0x0e, 0x1d, 0x58,
+ 0x7f, 0x40, 0x42, 0xa8, 0x46, 0xc6, 0xa1, 0x6f, 0x7f, 0xfa, 0x7f, 0x9a,
+ 0xe8, 0x3e, 0x7b, 0x5a, 0x8e, 0x1d, 0x7f, 0xfd, 0xd8, 0x9f, 0xe0, 0xe6,
+ 0xc7, 0xef, 0x63, 0x73, 0xaf, 0xff, 0xfb, 0x7d, 0x26, 0x33, 0xf3, 0xb9,
+ 0xed, 0x64, 0xff, 0x31, 0x02, 0x75, 0x05, 0x17, 0xd8, 0xa7, 0x7f, 0x4f,
+ 0xe9, 0x86, 0x16, 0x75, 0xff, 0xfd, 0x93, 0xe2, 0x04, 0x41, 0xdf, 0x90,
+ 0x17, 0x9b, 0x47, 0x56, 0x27, 0x74, 0x91, 0x87, 0x39, 0x16, 0x8b, 0xaa,
+ 0x75, 0xf8, 0x80, 0xb3, 0x29, 0x0e, 0xb6, 0xc6, 0x0f, 0xbc, 0x24, 0x10,
+ 0xaf, 0x90, 0xec, 0x5a, 0xa6, 0xa3, 0x13, 0xf4, 0x7c, 0x37, 0xfb, 0xc3,
+ 0x9e, 0xee, 0x4e, 0x75, 0xff, 0x9f, 0x9d, 0xcf, 0x40, 0xa7, 0xe7, 0x5f,
+ 0xff, 0x0e, 0x4f, 0xf3, 0xf0, 0x7b, 0x31, 0x7f, 0xb2, 0x75, 0xf4, 0xbc,
+ 0x93, 0x9d, 0x7f, 0xd8, 0xce, 0xf2, 0xd7, 0xcf, 0x21, 0xd7, 0xfe, 0x94,
+ 0x67, 0xfd, 0xcc, 0x16, 0x9d, 0x7f, 0xfb, 0xa8, 0x21, 0xf9, 0xf5, 0xa3,
+ 0x9d, 0xc3, 0xab, 0x11, 0x0f, 0x31, 0xe5, 0xff, 0x75, 0x17, 0x18, 0x3e,
+ 0xd1, 0xd7, 0xff, 0xf8, 0x1e, 0xe0, 0x26, 0xf9, 0xe9, 0xba, 0x0f, 0xfc,
+ 0x99, 0xb4, 0x75, 0xf4, 0x36, 0x17, 0xf1, 0x18, 0x6d, 0x23, 0x13, 0x6a,
+ 0x85, 0x56, 0x2d, 0x32, 0xe1, 0xe3, 0xaa, 0x09, 0x16, 0xd4, 0x70, 0xd7,
+ 0xff, 0xf7, 0x31, 0xd7, 0xf1, 0x47, 0xdf, 0xb9, 0xde, 0xc7, 0x8e, 0xbf,
+ 0xd0, 0xbc, 0xce, 0x4d, 0x23, 0xaf, 0x93, 0xc9, 0x07, 0x5f, 0xff, 0xfe,
+ 0x14, 0x53, 0xaf, 0x37, 0xc1, 0x06, 0xd7, 0xcc, 0xde, 0x58, 0x01, 0xff,
+ 0x47, 0x5f, 0xba, 0x90, 0x33, 0x9d, 0x77, 0xa1, 0x68, 0xa6, 0xd9, 0x08,
+ 0x0a, 0x92, 0x3e, 0x92, 0x18, 0xb5, 0x0c, 0xd1, 0xac, 0x9f, 0xa9, 0x49,
+ 0x6c, 0x5c, 0x5f, 0xea, 0xeb, 0xc6, 0x59, 0x7e, 0x81, 0xf2, 0x6c, 0x3a,
+ 0xfb, 0xda, 0x7f, 0xce, 0xbf, 0xfb, 0xa9, 0xf1, 0x38, 0x09, 0xdf, 0x8d,
+ 0x3a, 0xf9, 0x3a, 0xf3, 0x9d, 0x7d, 0xb2, 0x3d, 0x07, 0x5f, 0xb5, 0x9e,
+ 0x4d, 0x1d, 0x7e, 0x02, 0xa4, 0x5f, 0xc7, 0x5f, 0xdd, 0x79, 0xfe, 0x4b,
+ 0xc7, 0x5f, 0x9f, 0x83, 0xba, 0x1d, 0x50, 0x88, 0x04, 0x2a, 0xf1, 0x85,
+ 0x05, 0x3a, 0x6c, 0x27, 0x50, 0x89, 0xa8, 0xc8, 0x43, 0x31, 0x17, 0xa1,
+ 0x4d, 0x7f, 0xbb, 0x08, 0x2f, 0xc5, 0x0e, 0xbf, 0xa1, 0x05, 0xf8, 0xa1,
+ 0xd7, 0xfb, 0xf7, 0xff, 0x9c, 0x4e, 0x7c, 0x3d, 0xce, 0x98, 0xdb, 0xf3,
+ 0xaf, 0xe8, 0xe4, 0xf1, 0xc9, 0xce, 0xbc, 0x07, 0xd1, 0xd5, 0x23, 0xc9,
+ 0xfa, 0x5d, 0x7f, 0xff, 0x27, 0x3e, 0x62, 0x60, 0xa9, 0xd4, 0xc5, 0xe3,
+ 0x4e, 0xbf, 0xff, 0xe4, 0x9f, 0x90, 0xbd, 0x02, 0x3e, 0x47, 0x20, 0x3d,
+ 0x85, 0x9d, 0x58, 0x8c, 0x0e, 0x2c, 0xdf, 0xbf, 0xd2, 0x6e, 0xc9, 0xd7,
+ 0xfe, 0xe6, 0x6f, 0xdd, 0xe1, 0x73, 0xc1, 0xd7, 0xff, 0xff, 0xb9, 0xc4,
+ 0x9f, 0xe7, 0x73, 0xc3, 0x13, 0x77, 0x27, 0x8d, 0xfc, 0x06, 0x9d, 0x7f,
+ 0xff, 0xf4, 0x29, 0xd8, 0xf8, 0x38, 0x05, 0x3e, 0x6f, 0x2d, 0x20, 0xfd,
+ 0x89, 0xce, 0xbf, 0x6f, 0xa4, 0xc1, 0x3a, 0xb1, 0x13, 0xe0, 0x79, 0xa4,
+ 0x4c, 0xf7, 0xb1, 0x8d, 0xdf, 0xfd, 0x2d, 0x22, 0x9d, 0x84, 0x9e, 0x14,
+ 0x3a, 0xff, 0x84, 0x13, 0x0e, 0x75, 0xfc, 0x75, 0xfe, 0xec, 0x32, 0x1e,
+ 0xba, 0xce, 0xbf, 0xe5, 0xe6, 0xbe, 0x4c, 0x30, 0xb3, 0xa8, 0x27, 0xda,
+ 0xb3, 0x3b, 0xff, 0xfe, 0x7e, 0x77, 0x3c, 0x98, 0x33, 0xea, 0x30, 0x43,
+ 0xd8, 0x3a, 0xfb, 0xdf, 0x27, 0xe1, 0xd5, 0xba, 0x21, 0xdd, 0x8a, 0xff,
+ 0xff, 0xdb, 0xe4, 0xe0, 0xda, 0xf9, 0xbc, 0xbd, 0x0c, 0xfc, 0xce, 0x7f,
+ 0xfc, 0x1d, 0x7f, 0xf9, 0x97, 0x19, 0xd6, 0x04, 0x0a, 0x0a, 0x1d, 0x7f,
+ 0x4d, 0xbc, 0x81, 0x1e, 0x3a, 0xff, 0xba, 0xeb, 0x1c, 0xeb, 0xf8, 0xeb,
+ 0xec, 0xe7, 0xec, 0x9d, 0x50, 0x88, 0x8d, 0x17, 0xf8, 0xda, 0xfe, 0xcf,
+ 0x73, 0x99, 0x23, 0xaf, 0xe1, 0xce, 0x8e, 0x34, 0xeb, 0xe1, 0xcd, 0x7c,
+ 0x98, 0xf5, 0xbc, 0x59, 0x7f, 0xd8, 0xbe, 0xc2, 0x70, 0x0a, 0xe7, 0x50,
+ 0x57, 0x7a, 0xb0, 0x89, 0x42, 0xa6, 0xc6, 0xfb, 0xb9, 0x4a, 0x22, 0xf2,
+ 0x14, 0x9d, 0x85, 0x4b, 0x91, 0xe9, 0xe7, 0xd0, 0xd0, 0xd9, 0x08, 0x5f,
+ 0xa7, 0x77, 0xfe, 0xc6, 0x47, 0x01, 0x8a, 0x4b, 0xf3, 0xaf, 0xfc, 0x39,
+ 0xf3, 0x99, 0xd1, 0xc9, 0x8e, 0xbf, 0xff, 0xdd, 0x7f, 0xf5, 0xf0, 0x73,
+ 0x60, 0xe6, 0xb1, 0x70, 0xd3, 0xa8, 0x51, 0x41, 0xa3, 0xea, 0x55, 0x99,
+ 0x1f, 0x70, 0xb5, 0x93, 0xd9, 0xdb, 0xc3, 0x49, 0xe1, 0xbf, 0x7f, 0x67,
+ 0x7e, 0x8e, 0xff, 0x9d, 0x7f, 0x77, 0x07, 0xdf, 0x80, 0xeb, 0xf0, 0xc2,
+ 0xdc, 0x27, 0x5f, 0xec, 0x9b, 0xb9, 0xe8, 0x09, 0xd7, 0xf0, 0xf9, 0xd6,
+ 0x9e, 0x3a, 0xd2, 0x3a, 0xa0, 0xdd, 0xf8, 0xae, 0xf0, 0xb6, 0x0e, 0xbf,
+ 0xff, 0xfe, 0xee, 0x7b, 0x4f, 0x37, 0xc1, 0xcd, 0xe5, 0x80, 0x9c, 0x70,
+ 0x3d, 0x49, 0x8e, 0xb8, 0x0a, 0x1d, 0x48, 0x8b, 0x1e, 0x0d, 0x7a, 0x10,
+ 0x17, 0xf6, 0x4e, 0x39, 0xbe, 0x8e, 0xbf, 0xf8, 0x7f, 0xdb, 0xce, 0xa4,
+ 0x2d, 0xc2, 0x75, 0xff, 0xff, 0xfa, 0x5a, 0xd0, 0x23, 0xc8, 0x1c, 0x19,
+ 0xbe, 0x0e, 0x72, 0x07, 0xdd, 0xcd, 0xa3, 0xaf, 0xfe, 0xde, 0x5a, 0xc5,
+ 0xef, 0x1d, 0xec, 0x1d, 0x5b, 0xa3, 0x2b, 0x90, 0x85, 0xb6, 0x8e, 0xac,
+ 0x4d, 0x20, 0x11, 0x87, 0xfd, 0x29, 0xbf, 0xb3, 0x79, 0x47, 0xf0, 0x75,
+ 0xf8, 0x73, 0xaf, 0xe3, 0xad, 0x1b, 0x9e, 0x92, 0xcb, 0x6f, 0xbe, 0x36,
+ 0x76, 0x4e, 0xbf, 0x4f, 0xf0, 0x11, 0x31, 0xd7, 0xff, 0xfc, 0x31, 0xfe,
+ 0xf2, 0xd0, 0x23, 0xc3, 0x81, 0x4c, 0xe4, 0xc7, 0x53, 0xa2, 0x47, 0xc5,
+ 0x75, 0x0b, 0x9e, 0x81, 0x30, 0x42, 0xd9, 0x89, 0x7a, 0xda, 0xf0, 0xd1,
+ 0x13, 0x4d, 0x46, 0xea, 0x08, 0x45, 0x6c, 0x28, 0xfb, 0x0b, 0x7b, 0xf4,
+ 0x93, 0x99, 0xb9, 0xd7, 0xb5, 0xdc, 0x3a, 0xfd, 0x9a, 0x9f, 0x19, 0x3a,
+ 0xb7, 0x3e, 0xa9, 0x89, 0xfa, 0x37, 0x7f, 0xfd, 0x3e, 0x34, 0x3d, 0x4c,
+ 0x53, 0xe2, 0x80, 0x83, 0xaf, 0xfb, 0xe7, 0xdf, 0x26, 0xc8, 0x16, 0x9d,
+ 0x48, 0x89, 0x0e, 0xa9, 0xdf, 0xfe, 0x8d, 0xe5, 0xaf, 0x3c, 0xfb, 0x43,
+ 0x9b, 0x9d, 0x7f, 0xdd, 0x9d, 0x30, 0x77, 0x96, 0x8e, 0xbf, 0xed, 0xfb,
+ 0x8d, 0x1c, 0x02, 0xb9, 0xd6, 0x94, 0x1f, 0xa6, 0x1c, 0xdf, 0xc9, 0xbf,
+ 0xfc, 0x70, 0x9d, 0x7e, 0xc4, 0xce, 0x7e, 0x75, 0x74, 0xf5, 0x04, 0xba,
+ 0xfb, 0x6b, 0xd9, 0xd3, 0xae, 0x45, 0x9d, 0x7f, 0xff, 0xed, 0xe4, 0xfb,
+ 0xfc, 0x10, 0x6d, 0x7c, 0xcd, 0xe5, 0x80, 0x1f, 0xf4, 0x75, 0x2d, 0x11,
+ 0x7b, 0x42, 0xb7, 0xb6, 0xd1, 0x52, 0x75, 0x7c, 0x4c, 0x62, 0x72, 0x1c,
+ 0x85, 0x7e, 0xd9, 0x35, 0xff, 0xff, 0xfa, 0x37, 0xd0, 0x23, 0x7f, 0x9d,
+ 0xc0, 0xfc, 0x1c, 0x02, 0x9f, 0x35, 0xff, 0xe9, 0xe3, 0xaf, 0xd0, 0x3b,
+ 0xbc, 0xe7, 0x5f, 0xff, 0xff, 0xfb, 0x1b, 0x1d, 0x85, 0xfb, 0x35, 0xa8,
+ 0xe7, 0x20, 0x72, 0x7c, 0x06, 0x81, 0x30, 0xc2, 0xce, 0xbc, 0x0e, 0x28,
+ 0x75, 0x2d, 0x16, 0x9b, 0x70, 0x97, 0xbf, 0x3f, 0xff, 0x5e, 0x73, 0xab,
+ 0x0f, 0x55, 0x0a, 0xef, 0x27, 0xf0, 0x75, 0xfc, 0x11, 0xce, 0xbf, 0x8e,
+ 0xbf, 0x7b, 0x79, 0x27, 0x0e, 0xac, 0x3d, 0x3d, 0x15, 0xd4, 0xe8, 0x8f,
+ 0xfd, 0xba, 0xff, 0x4e, 0x08, 0xf2, 0xd3, 0xc7, 0x5f, 0xfa, 0x14, 0xda,
+ 0x06, 0x0c, 0xdf, 0x56, 0x75, 0x61, 0xfb, 0xee, 0x67, 0x7f, 0xec, 0xcf,
+ 0xf5, 0xf3, 0x9a, 0x0e, 0x8e, 0xbf, 0xdc, 0xc6, 0xf5, 0x39, 0x31, 0xd7,
+ 0x67, 0x82, 0x7e, 0x98, 0x83, 0x7d, 0x3a, 0x0f, 0x8e, 0xbf, 0x67, 0x7a,
+ 0xf2, 0x3a, 0xfe, 0xf2, 0x72, 0x7c, 0x69, 0xd5, 0x0b, 0xf7, 0xb9, 0x0c,
+ 0x15, 0x08, 0xb7, 0x86, 0x12, 0x47, 0x25, 0xc4, 0x85, 0xc2, 0x37, 0xb1,
+ 0x98, 0x3c, 0x2b, 0xc6, 0x13, 0x9a, 0x84, 0xb0, 0x0b, 0x36, 0xc8, 0x76,
+ 0x89, 0xaf, 0x3b, 0x70, 0xeb, 0xff, 0x4d, 0xf3, 0xc3, 0x8c, 0xe2, 0x68,
+ 0xea, 0x55, 0x1e, 0xd4, 0x0d, 0x51, 0xd7, 0xf6, 0x2e, 0x3a, 0xfd, 0x3a,
+ 0xef, 0x93, 0x1d, 0x5f, 0x0f, 0x10, 0x25, 0x77, 0xff, 0xdb, 0xc8, 0x63,
+ 0xe2, 0xc6, 0x14, 0xf2, 0x4e, 0x75, 0x42, 0x31, 0x31, 0x39, 0x09, 0x2f,
+ 0xdc, 0xf8, 0x3b, 0x19, 0x3a, 0xfb, 0xaf, 0xfc, 0x1d, 0x7b, 0xb9, 0xc3,
+ 0xaa, 0x0f, 0xa1, 0xcb, 0x36, 0x88, 0x6f, 0xe9, 0xe6, 0x92, 0xab, 0x93,
+ 0x9d, 0x7e, 0x5a, 0x07, 0x02, 0x75, 0xa6, 0x3a, 0xe8, 0x59, 0xd6, 0xf1,
+ 0xd5, 0xc3, 0x4a, 0xe2, 0xb4, 0x13, 0xd6, 0xe9, 0xb5, 0xee, 0x44, 0xc7,
+ 0x5e, 0xd3, 0xee, 0x75, 0x39, 0xb8, 0xf0, 0xe5, 0xd3, 0x39, 0xd7, 0xf3,
+ 0xb3, 0x1e, 0xc9, 0xce, 0xbf, 0x93, 0x9b, 0xc8, 0x60, 0xeb, 0xfc, 0x1e,
+ 0xc6, 0xf2, 0xcf, 0x1d, 0x5d, 0x3d, 0xff, 0x16, 0x52, 0xb2, 0x9f, 0x7c,
+ 0x1a, 0xe3, 0xe2, 0x2d, 0x2c, 0x80, 0x45, 0x81, 0x08, 0xcb, 0xfc, 0xce,
+ 0x48, 0x40, 0xfa, 0x3a, 0xfd, 0xbb, 0x2e, 0x3f, 0x9d, 0x70, 0xa8, 0x75,
+ 0xb4, 0x86, 0xfc, 0x05, 0x37, 0xff, 0xf4, 0x2c, 0x71, 0xbb, 0xf8, 0x5f,
+ 0xab, 0x8c, 0xf1, 0xd7, 0xff, 0xe8, 0xe4, 0x37, 0x17, 0x0d, 0x92, 0x68,
+ 0x0b, 0x3a, 0xa1, 0x34, 0x29, 0x9c, 0x7a, 0x4d, 0xb6, 0xb1, 0x7f, 0x73,
+ 0x21, 0x48, 0x13, 0xaf, 0x0b, 0xac, 0xeb, 0xbf, 0x83, 0xaa, 0x47, 0xb6,
+ 0x85, 0x62, 0x35, 0x4a, 0xcb, 0xf0, 0x0c, 0x2b, 0x6e, 0xca, 0xa8, 0xfb,
+ 0x95, 0xa2, 0xcc, 0x4b, 0x87, 0x9e, 0x3a, 0x09, 0x42, 0x08, 0x33, 0x95,
+ 0x79, 0x4b, 0x6e, 0x52, 0x52, 0xbb, 0x67, 0x77, 0x77, 0x97, 0xac, 0x92,
+ 0x8b, 0x26, 0x94, 0xe9, 0xc9, 0xc1, 0x55, 0xcb, 0x2c, 0xed, 0x38, 0x09,
+ 0xe5, 0x09, 0x7f, 0x0c, 0x61, 0xa4, 0xa4, 0xea, 0x75, 0x5f, 0xd4, 0x8d,
+ 0x80, 0x46, 0x93, 0xb2, 0x1d, 0x2c, 0xc2, 0x57, 0x6e, 0x50, 0xff, 0xd8,
+ 0xeb, 0x76, 0xa1, 0x39, 0x7f, 0xff, 0x01, 0xac, 0x6f, 0xee, 0x46, 0x6e,
+ 0xaa, 0x0b, 0xba, 0x87, 0x53, 0x0a, 0xaa, 0x92, 0x52, 0x45, 0xfe, 0x57,
+ 0x74, 0xf6, 0x90, 0x4e, 0xbf, 0x71, 0xae, 0xed, 0x34, 0x53, 0xb7, 0x66,
+ 0xe7, 0x5f, 0xfe, 0x00, 0x05, 0x06, 0x3a, 0x8b, 0xcd, 0x1d, 0x66, 0x21,
+ 0x18, 0x58, 0x67, 0xb9, 0x9a, 0xc5, 0xaf, 0xdc, 0x6b, 0xbb, 0x4d, 0x15,
+ 0x1d, 0xff, 0x9e, 0x4c, 0x67, 0x1a, 0xee, 0xd3, 0x44, 0xd1, 0x7c, 0x31,
+ 0x9b, 0x9d, 0x58, 0x89, 0xd5, 0x99, 0xf9, 0x2a, 0xff, 0x7d, 0x7d, 0x8c,
+ 0x79, 0x27, 0x3a, 0x98, 0x3e, 0x78, 0x2f, 0xbf, 0x71, 0xae, 0xed, 0x34,
+ 0x55, 0xf7, 0xf6, 0x6c, 0x81, 0xe8, 0x0e, 0xb3, 0x18, 0x7c, 0x1c, 0x33,
+ 0xbf, 0x71, 0xae, 0xed, 0x34, 0x56, 0xd7, 0xfd, 0x26, 0x33, 0x8d, 0x77,
+ 0x69, 0xa2, 0x41, 0xb3, 0x18, 0x7f, 0x0e, 0x67, 0x7f, 0xf3, 0x0f, 0x26,
+ 0x33, 0x8d, 0x77, 0x69, 0xa2, 0x43, 0xbf, 0xf6, 0x98, 0xcf, 0x20, 0x70,
+ 0x66, 0x3a, 0xf3, 0xbb, 0x4f, 0x18, 0x1d, 0x41, 0xf2, 0xb4, 0xfa, 0xee,
+ 0xab, 0x9d, 0x7f, 0xe9, 0x76, 0x3d, 0xa5, 0x63, 0x4a, 0xd8, 0x9d, 0x7f,
+ 0xf9, 0x57, 0x2a, 0xe5, 0x63, 0xb0, 0xb1, 0x7e, 0xa7, 0x0e, 0xb6, 0xe7,
+ 0x5c, 0x82, 0x75, 0xfd, 0x01, 0x8f, 0x38, 0x4e, 0xa0, 0x9e, 0x84, 0xc2,
+ 0x3e, 0x14, 0xbf, 0xf9, 0x06, 0x78, 0x53, 0xef, 0xff, 0xc6, 0xe7, 0x5f,
+ 0xb3, 0x07, 0xfd, 0x1d, 0x7e, 0x70, 0xfd, 0x81, 0x3a, 0xff, 0xdc, 0xf7,
+ 0xd1, 0x76, 0xe0, 0xb4, 0xeb, 0xe6, 0xbb, 0xb4, 0xd1, 0x62, 0x5e, 0x00,
+ 0xc8, 0xeb, 0xfc, 0xd8, 0xce, 0x7f, 0xff, 0x8e, 0xa9, 0xd1, 0xc3, 0x84,
+ 0xfc, 0x3e, 0xf1, 0x68, 0x06, 0xef, 0xd9, 0xc8, 0x15, 0x0e, 0xbf, 0x7d,
+ 0xdb, 0xce, 0x41, 0xd7, 0xb5, 0x02, 0x75, 0xbb, 0x07, 0x8a, 0x85, 0x77,
+ 0xff, 0x46, 0x6b, 0x04, 0x29, 0xfc, 0x09, 0xd7, 0x86, 0x27, 0x3a, 0x84,
+ 0xf6, 0xc0, 0x81, 0x7d, 0x1c, 0x85, 0x9d, 0x52, 0x3c, 0x1d, 0x10, 0xde,
+ 0x5b, 0xf8, 0xeb, 0x93, 0xf3, 0xab, 0x86, 0xc7, 0x6c, 0x6e, 0xfc, 0x9b,
+ 0x00, 0xfa, 0x3a, 0xff, 0x83, 0xdc, 0x5e, 0x3f, 0x27, 0x3a, 0xfd, 0xef,
+ 0x3c, 0xb4, 0x75, 0xff, 0x81, 0x9b, 0x87, 0x67, 0x71, 0xe6, 0x3a, 0xb7,
+ 0x3e, 0x8d, 0x84, 0xf6, 0x91, 0xd7, 0xd9, 0x8c, 0xe8, 0xea, 0x83, 0x63,
+ 0xe1, 0x0b, 0x80, 0x27, 0x54, 0x26, 0x57, 0x90, 0xa0, 0xe2, 0xb6, 0x88,
+ 0x2f, 0xfa, 0x35, 0xf7, 0x39, 0x99, 0x31, 0xd7, 0xf7, 0x25, 0xfe, 0x64,
+ 0xc7, 0x5f, 0x3c, 0x26, 0xd9, 0xd5, 0x87, 0xa1, 0xc2, 0xeb, 0xe9, 0x7d,
+ 0xec, 0x1d, 0x7b, 0x91, 0x23, 0xa9, 0xcd, 0xf6, 0xc2, 0x3b, 0xfa, 0x17,
+ 0x89, 0xc9, 0x8e, 0xbe, 0xfb, 0x1b, 0x5a, 0x3a, 0xfd, 0x81, 0xec, 0x74,
+ 0xeb, 0xee, 0x23, 0x2a, 0xe7, 0x50, 0x9e, 0x5e, 0x89, 0xa8, 0x28, 0x92,
+ 0xd3, 0x8d, 0x42, 0x6c, 0x48, 0xbf, 0xd2, 0x27, 0x85, 0xf5, 0xfc, 0x82,
+ 0xeb, 0x8e, 0x9d, 0x7f, 0xfa, 0x17, 0x12, 0x08, 0xc7, 0x5f, 0x38, 0x75,
+ 0x1d, 0x52, 0x3d, 0x0d, 0xb4, 0x6b, 0xde, 0xcf, 0xce, 0xbf, 0x96, 0x9a,
+ 0xd2, 0x04, 0xeb, 0xcf, 0xc5, 0x0e, 0xa0, 0x1e, 0x43, 0x25, 0x97, 0xf9,
+ 0xa3, 0x9b, 0x07, 0x34, 0x75, 0xff, 0x6f, 0x27, 0xc1, 0xcf, 0x68, 0xeb,
+ 0xff, 0x66, 0xf2, 0xec, 0x69, 0x4e, 0xc1, 0xd5, 0x24, 0xf3, 0xb7, 0x7a,
+ 0x98, 0x97, 0x8c, 0x9d, 0x23, 0x13, 0x2d, 0xa3, 0x7b, 0x6d, 0x9d, 0x74,
+ 0xb4, 0x75, 0x9e, 0x46, 0xa7, 0x71, 0x3b, 0xef, 0x20, 0xb2, 0x55, 0x80,
+ 0x75, 0xa3, 0x0d, 0x8f, 0x48, 0x6f, 0xf9, 0xc7, 0xda, 0xdf, 0x4e, 0xae,
+ 0x75, 0x3a, 0x2e, 0x3f, 0x58, 0x01, 0x2d, 0xfd, 0xd4, 0xd7, 0x39, 0x87,
+ 0x5f, 0xfa, 0x19, 0xfb, 0x3e, 0xb1, 0x70, 0xae, 0x75, 0xce, 0xc9, 0xd6,
+ 0xc6, 0xa2, 0x1b, 0xc5, 0x9b, 0x11, 0x2f, 0xfe, 0xeb, 0xa7, 0xa5, 0x8a,
+ 0x0e, 0x7e, 0x75, 0xf8, 0x66, 0x8e, 0xc1, 0xd7, 0xec, 0xee, 0xee, 0xae,
+ 0x75, 0xf7, 0xfa, 0x81, 0x3a, 0xff, 0x73, 0xae, 0x9a, 0x4d, 0x87, 0x54,
+ 0x1e, 0xa6, 0x10, 0xd2, 0x26, 0x0e, 0xe8, 0x62, 0x4d, 0xa7, 0xeb, 0xf9,
+ 0x98, 0xe7, 0x1e, 0x63, 0xaf, 0xf8, 0x30, 0xdf, 0xbf, 0xff, 0x1b, 0x9d,
+ 0x7f, 0xcf, 0xcc, 0x5a, 0x6d, 0xc2, 0xce, 0xa6, 0x9f, 0xb0, 0x0f, 0x6f,
+ 0xbd, 0x1b, 0xc8, 0xeb, 0xf9, 0x3f, 0xdb, 0x14, 0xfc, 0xea, 0x9c, 0xf4,
+ 0xb8, 0x45, 0x50, 0x99, 0xde, 0x42, 0x91, 0xdd, 0x2f, 0xed, 0x9c, 0x78,
+ 0x4d, 0xb3, 0xad, 0x87, 0x52, 0xcd, 0xf8, 0x98, 0x5f, 0xfb, 0xb8, 0x10,
+ 0xa6, 0xf9, 0xbf, 0x8e, 0xbf, 0xbe, 0x07, 0xeb, 0xf3, 0x87, 0x54, 0xe7,
+ 0xe0, 0x13, 0xfb, 0xe7, 0x84, 0xdb, 0x3a, 0xff, 0xa1, 0x03, 0xe1, 0x7d,
+ 0xf4, 0x75, 0x41, 0xfe, 0x04, 0x8c, 0x48, 0xa9, 0x58, 0x6c, 0x19, 0x15,
+ 0xb1, 0x95, 0x6a, 0x91, 0x10, 0xa9, 0x91, 0x80, 0x52, 0x72, 0x30, 0x75,
+ 0x12, 0x9a, 0xd7, 0xbc, 0x30, 0x91, 0x4e, 0x62, 0x4e, 0x46, 0xa6, 0xb4,
+ 0x1e, 0xc7, 0xd6, 0xf2, 0x83, 0xbf, 0x8d, 0x28, 0x61, 0x6d, 0xa8, 0xcf,
+ 0xbd, 0x1b, 0xb0, 0x1c, 0xbe, 0xc6, 0x19, 0x7f, 0xf7, 0x52, 0x3d, 0xd7,
+ 0x53, 0x07, 0xf3, 0xaf, 0xec, 0xf4, 0x22, 0xf4, 0x75, 0xfe, 0x0c, 0x4b,
+ 0x39, 0x9a, 0x3a, 0xf6, 0xbe, 0xe8, 0xeb, 0xff, 0xec, 0xde, 0x5e, 0x04,
+ 0xec, 0x75, 0xd6, 0x9a, 0x3a, 0xff, 0x80, 0xf8, 0x14, 0xdc, 0x5c, 0xeb,
+ 0xde, 0x18, 0x3a, 0xee, 0xb1, 0x89, 0xaf, 0xcc, 0x86, 0xb2, 0xb7, 0x31,
+ 0x11, 0xed, 0x29, 0x7d, 0x36, 0xa6, 0x15, 0xa7, 0x44, 0xad, 0xcb, 0xfb,
+ 0x38, 0xd7, 0x76, 0x9a, 0x2c, 0xdb, 0xff, 0x47, 0x3f, 0xf6, 0xbb, 0x88,
+ 0x13, 0xaf, 0x90, 0x5e, 0x73, 0xab, 0xa7, 0xbd, 0xa3, 0xeb, 0xe6, 0x3b,
+ 0x1d, 0x3a, 0x98, 0x3c, 0x4d, 0xa2, 0x2a, 0x61, 0x30, 0x07, 0x86, 0xd5,
+ 0xfe, 0x5b, 0x10, 0x8b, 0xfb, 0xc3, 0xae, 0xc0, 0x9d, 0x7f, 0xe7, 0x93,
+ 0x19, 0xc6, 0xbb, 0xb4, 0xd1, 0x40, 0x5f, 0xe4, 0x5c, 0x2b, 0xf7, 0x27,
+ 0x3a, 0xcc, 0x62, 0x25, 0x16, 0x2b, 0xd4, 0xab, 0xf9, 0xfd, 0xa9, 0x27,
+ 0xe7, 0x5f, 0xd2, 0x63, 0x26, 0x89, 0x1d, 0x4c, 0x1e, 0xdc, 0x16, 0xdc,
+ 0x0e, 0x9d, 0x7f, 0x6a, 0x16, 0x31, 0x31, 0xd6, 0xe9, 0xd7, 0xbe, 0x8c,
+ 0xc7, 0x5d, 0x9e, 0xc3, 0x5d, 0xf8, 0x85, 0x7e, 0x88, 0x61, 0x5a, 0xbb,
+ 0xe6, 0x8e, 0xbc, 0x00, 0xe1, 0xd7, 0xfb, 0x39, 0xe1, 0x85, 0xe8, 0xeb,
+ 0x6d, 0x9d, 0x48, 0x7b, 0xfd, 0x1b, 0xfc, 0xc6, 0xf9, 0xae, 0xed, 0x34,
+ 0x5b, 0xf7, 0xb6, 0xdf, 0xc7, 0x5f, 0xdf, 0x7c, 0xed, 0x7e, 0x1d, 0x5c,
+ 0x3f, 0x95, 0x96, 0xfe, 0x3d, 0x7d, 0x82, 0x93, 0x1d, 0x7e, 0xf4, 0xb5,
+ 0xf7, 0x47, 0x5e, 0xd7, 0x42, 0x75, 0xfb, 0xef, 0x86, 0x3f, 0x3a, 0x96,
+ 0x78, 0xbb, 0x07, 0x2f, 0xfe, 0xf6, 0x93, 0x50, 0x39, 0xee, 0xa1, 0xd7,
+ 0x87, 0x3a, 0x75, 0x2c, 0xf6, 0xf6, 0x20, 0xdf, 0x83, 0x0a, 0xe0, 0x59,
+ 0xd7, 0xfc, 0xfa, 0x8c, 0x10, 0xf6, 0x0e, 0xbf, 0xfb, 0x17, 0xcc, 0xdf,
+ 0xa2, 0xea, 0xf3, 0x9d, 0x76, 0xb5, 0xc3, 0xfc, 0x13, 0x5a, 0x84, 0xdd,
+ 0xb1, 0xfd, 0x09, 0x1e, 0x14, 0xd7, 0xce, 0x83, 0xe3, 0xaf, 0x72, 0x3c,
+ 0x75, 0xfd, 0x33, 0x87, 0xa8, 0xb3, 0xaf, 0xef, 0x26, 0x06, 0x16, 0x75,
+ 0x78, 0xf6, 0x19, 0x2d, 0xbb, 0x42, 0x75, 0xfd, 0xbe, 0xa1, 0xb8, 0xb3,
+ 0xab, 0x88, 0xd8, 0x77, 0x3d, 0x11, 0x80, 0x56, 0xfb, 0xaa, 0x05, 0x67,
+ 0x5d, 0x92, 0x3a, 0xb0, 0xdc, 0x09, 0x1d, 0x2b, 0x6b, 0xbb, 0x91, 0x09,
+ 0xc9, 0x11, 0x85, 0xdf, 0x21, 0x50, 0x86, 0x1c, 0x20, 0xec, 0x7c, 0xbf,
+ 0x9f, 0x8c, 0x3d, 0xfc, 0xe9, 0x7f, 0x3e, 0xec, 0x2d, 0xfc, 0x75, 0x30,
+ 0x8e, 0x01, 0x85, 0x95, 0xfc, 0x16, 0x35, 0xed, 0x6e, 0x75, 0xca, 0xca,
+ 0xb6, 0x75, 0xe5, 0xbe, 0xe7, 0x5d, 0xb1, 0x0e, 0xbe, 0xe7, 0x33, 0xe9,
+ 0xd7, 0xed, 0x4f, 0x8c, 0xb0, 0xac, 0x1f, 0xb4, 0x10, 0x4c, 0x38, 0xe2,
+ 0xf5, 0x09, 0x83, 0x24, 0x29, 0xaf, 0xff, 0xff, 0x23, 0x5f, 0x8f, 0xd9,
+ 0x67, 0xb0, 0x3a, 0x75, 0xe7, 0x27, 0x8d, 0xce, 0xbf, 0x71, 0xae, 0xed,
+ 0x34, 0x52, 0x97, 0xff, 0xcf, 0xe1, 0xc9, 0xf9, 0x1d, 0x4e, 0xe7, 0x0e,
+ 0xbc, 0xf2, 0x62, 0x11, 0xed, 0x8e, 0xdf, 0x99, 0xdf, 0xf4, 0x98, 0xce,
+ 0x35, 0xdd, 0xa6, 0x89, 0x3a, 0xcc, 0x2d, 0x10, 0xce, 0x83, 0x51, 0x08,
+ 0xd0, 0x09, 0xe7, 0x05, 0x25, 0x1b, 0xd0, 0x6f, 0x8b, 0x93, 0x21, 0xdc,
+ 0xd8, 0xd1, 0xd2, 0x10, 0x4a, 0xf0, 0xa0, 0x98, 0x9f, 0x90, 0xb6, 0x5d,
+ 0x67, 0xa7, 0xd8, 0xcb, 0x1c, 0xa7, 0xf8, 0x64, 0x8c, 0x24, 0x75, 0x3d,
+ 0xbd, 0xe8, 0xcb, 0xb6, 0x47, 0x47, 0x7e, 0xe3, 0x5d, 0xda, 0x68, 0x87,
+ 0xef, 0xfc, 0xf2, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x25, 0x3b, 0x31, 0x87,
+ 0xfa, 0xb3, 0x3b, 0xfc, 0xc6, 0x71, 0xae, 0xed, 0x34, 0x44, 0xf7, 0xf4,
+ 0xc9, 0xed, 0x01, 0x67, 0x5f, 0xfe, 0x55, 0x94, 0x65, 0x5e, 0x70, 0xaa,
+ 0xbe, 0x7c, 0xee, 0xd9, 0xd7, 0xee, 0x35, 0xdd, 0xa6, 0x88, 0xc6, 0xff,
+ 0xfd, 0xfc, 0xa7, 0x55, 0xa1, 0x5b, 0x9d, 0xbc, 0xf9, 0xf3, 0xbb, 0x67,
+ 0x5f, 0x26, 0xf2, 0x56, 0xce, 0xb3, 0x10, 0x9a, 0xac, 0x8b, 0xb1, 0x8b,
+ 0xa6, 0x7e, 0x6b, 0xbf, 0xfc, 0xc2, 0xde, 0x4c, 0x67, 0x1a, 0xee, 0xd3,
+ 0x44, 0xf3, 0x7f, 0x31, 0xfc, 0x0c, 0xb4, 0x75, 0x42, 0xa9, 0x19, 0xca,
+ 0x25, 0x1c, 0xa7, 0x54, 0x3c, 0xaf, 0x7e, 0xe3, 0x5d, 0xda, 0x68, 0x88,
+ 0x2f, 0xfc, 0xf2, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x25, 0x4b, 0x31, 0x87,
+ 0xfa, 0xb3, 0x3b, 0xfc, 0xc6, 0x71, 0xae, 0xed, 0x34, 0x45, 0x17, 0xf9,
+ 0x8c, 0xe3, 0x5d, 0xda, 0x68, 0x8c, 0xaf, 0xdc, 0x6b, 0xbb, 0x4d, 0x13,
+ 0x2d, 0xfa, 0x59, 0xe7, 0x69, 0xd7, 0xe6, 0x16, 0xf2, 0x63, 0x0f, 0x67,
+ 0x73, 0x3b, 0xf7, 0x1a, 0xee, 0xd3, 0x45, 0x49, 0x61, 0x3a, 0xdf, 0x4e,
+ 0xb3, 0x18, 0x7a, 0x8a, 0xe6, 0x60, 0x0f, 0xbf, 0xcc, 0x67, 0x1a, 0xee,
+ 0xd3, 0x45, 0x75, 0x7f, 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x8b, 0x16, 0xff,
+ 0xe5, 0xbc, 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x89, 0xea, 0xff, 0x99, 0x61,
+ 0xe1, 0x36, 0xd3, 0x68, 0xeb, 0xff, 0xf4, 0xc3, 0x0b, 0x63, 0x34, 0x8c,
+ 0x85, 0xdd, 0x43, 0xae, 0xd7, 0x8e, 0xbf, 0x0b, 0xac, 0x60, 0xeb, 0xf8,
+ 0x1a, 0xeb, 0xc9, 0x85, 0x6c, 0xdd, 0x7d, 0x16, 0xbf, 0x67, 0xb4, 0x8b,
+ 0x3a, 0xff, 0xf4, 0x6f, 0xec, 0x99, 0x39, 0xed, 0x01, 0x5c, 0xeb, 0xcf,
+ 0xbb, 0x02, 0x7e, 0x9e, 0x26, 0xb7, 0xb1, 0x38, 0x4e, 0x42, 0x43, 0x50,
+ 0xc0, 0xa6, 0x15, 0x29, 0x42, 0x82, 0x47, 0x85, 0x7e, 0x4e, 0x8b, 0xcc,
+ 0x75, 0xfa, 0x58, 0x1f, 0x98, 0x75, 0x2a, 0x0f, 0x3a, 0x09, 0xaf, 0xd9,
+ 0xe4, 0x06, 0x8e, 0xb9, 0x58, 0x56, 0xa7, 0x52, 0xb5, 0x3c, 0x75, 0x58,
+ 0x9a, 0xfc, 0xab, 0x95, 0x8d, 0x73, 0xc7, 0x5f, 0xef, 0xa3, 0x9c, 0xe4,
+ 0x34, 0xea, 0x56, 0x0f, 0x99, 0x54, 0x67, 0x7d, 0xc5, 0xfb, 0x73, 0xaf,
+ 0xe5, 0x61, 0x59, 0x54, 0x44, 0x96, 0x75, 0xe6, 0xe7, 0x4a, 0xbc, 0xb8,
+ 0xd1, 0xd7, 0xbf, 0xe4, 0x1d, 0x7f, 0x67, 0xe9, 0x32, 0x32, 0x75, 0xff,
+ 0x9f, 0x5f, 0x35, 0xac, 0x94, 0xa0, 0xeb, 0xff, 0xf0, 0xba, 0x89, 0xc8,
+ 0x94, 0xb3, 0x5f, 0xff, 0x07, 0x50, 0x51, 0x84, 0xa1, 0x77, 0x4f, 0xef,
+ 0xff, 0xee, 0x26, 0xd3, 0xad, 0x88, 0xe7, 0x13, 0x69, 0xa0, 0x9c, 0xeb,
+ 0xe4, 0xef, 0xd5, 0x9d, 0x7f, 0xf9, 0x14, 0xf9, 0x82, 0xfb, 0xe9, 0x45,
+ 0x1c, 0xea, 0x69, 0xf8, 0x09, 0x1d, 0xff, 0xe7, 0xd0, 0xe7, 0xec, 0x75,
+ 0x1a, 0xfc, 0x3a, 0xfe, 0x0e, 0x29, 0xec, 0x69, 0xd7, 0xdd, 0x85, 0xb4,
+ 0xea, 0x73, 0xce, 0xf1, 0x6d, 0xf8, 0x29, 0x32, 0x32, 0x75, 0xff, 0xdf,
+ 0x22, 0x06, 0x17, 0xf3, 0xe7, 0x76, 0xce, 0xa8, 0x3f, 0x31, 0x28, 0xbf,
+ 0xf7, 0x72, 0x6e, 0xa7, 0x63, 0x90, 0x75, 0xcf, 0xb9, 0xd7, 0xf9, 0xf4,
+ 0xfd, 0x00, 0xce, 0x75, 0x09, 0xe4, 0x00, 0x5a, 0xa7, 0x5c, 0x0e, 0x90,
+ 0xda, 0x43, 0x7b, 0x86, 0x2b, 0x86, 0x97, 0x48, 0x46, 0x12, 0xfe, 0x84,
+ 0xa7, 0xd2, 0x0d, 0xa8, 0x42, 0xde, 0x17, 0xf1, 0xd7, 0x85, 0x34, 0x75,
+ 0x99, 0x54, 0x1b, 0x48, 0x1a, 0xbe, 0xe6, 0xc7, 0x59, 0xd7, 0xe5, 0x8b,
+ 0xfb, 0x47, 0x5e, 0x8c, 0xe1, 0xd7, 0xff, 0x9a, 0xfc, 0x7f, 0x26, 0xa0,
+ 0x63, 0xf3, 0xad, 0x2e, 0x9f, 0x0f, 0xd1, 0xaa, 0xdd, 0x16, 0x3c, 0x84,
+ 0x3d, 0x62, 0x65, 0x08, 0x56, 0x08, 0x6a, 0x5e, 0xd6, 0xd6, 0xd1, 0xd7,
+ 0xfd, 0xd7, 0xf4, 0x4d, 0xa4, 0x59, 0xd7, 0xfa, 0x24, 0x39, 0xbf, 0xb0,
+ 0xeb, 0xdd, 0x02, 0xce, 0xac, 0x45, 0x3a, 0x11, 0x70, 0xe0, 0x06, 0x37,
+ 0xf7, 0xb5, 0x34, 0x0c, 0xe7, 0x5f, 0x85, 0x44, 0xcd, 0x1d, 0x7e, 0x65,
+ 0xfc, 0xed, 0x3a, 0xff, 0xec, 0x65, 0xff, 0xc6, 0xf5, 0xff, 0xd1, 0xd7,
+ 0xfe, 0xd3, 0xef, 0x02, 0xe1, 0xc5, 0x0e, 0xa4, 0x46, 0x7f, 0x49, 0x84,
+ 0x9f, 0xc8, 0xb7, 0x47, 0x4e, 0xb0, 0x4e, 0xa5, 0x9a, 0x51, 0x15, 0xbe,
+ 0x10, 0xfc, 0x50, 0xeb, 0xfb, 0x34, 0xcb, 0x8c, 0xe7, 0x56, 0x1f, 0x8b,
+ 0x90, 0x09, 0x25, 0xf8, 0x0a, 0x68, 0x30, 0x75, 0xe5, 0xa6, 0x8e, 0xbf,
+ 0xa3, 0x79, 0x69, 0x04, 0xea, 0x85, 0x4d, 0x39, 0x0f, 0xd4, 0x86, 0x8f,
+ 0x4b, 0x1c, 0xa0, 0x46, 0xef, 0xff, 0x28, 0xf9, 0xbf, 0xbd, 0x19, 0xb1,
+ 0x1a, 0x75, 0xfe, 0x1c, 0xd7, 0x9d, 0xc4, 0xea, 0x50, 0xfe, 0xb6, 0x25,
+ 0xdf, 0xff, 0xf9, 0x39, 0xc8, 0xfb, 0xe4, 0x10, 0x4b, 0x34, 0x10, 0x3f,
+ 0x24, 0x75, 0xff, 0xfc, 0x38, 0xa6, 0x0f, 0xcd, 0x7b, 0xb8, 0xbf, 0xb1,
+ 0xf9, 0xd5, 0x08, 0xca, 0xc6, 0xcb, 0xfc, 0x07, 0xd2, 0x4c, 0x8c, 0x9d,
+ 0x48, 0x9a, 0x1f, 0x61, 0xde, 0x24, 0x37, 0xbb, 0x02, 0x75, 0xed, 0xfc,
+ 0xb3, 0xa9, 0xa6, 0xdd, 0xc6, 0xaf, 0xd3, 0x87, 0x88, 0xc9, 0xd7, 0xfb,
+ 0xeb, 0xec, 0x49, 0x91, 0x93, 0xaf, 0xfe, 0x41, 0xc0, 0x72, 0x75, 0xc6,
+ 0x78, 0xea, 0x83, 0xf9, 0x09, 0xbd, 0xfc, 0x17, 0xe7, 0xfb, 0x78, 0x75,
+ 0xee, 0xfd, 0xd8, 0x75, 0xff, 0x42, 0xc7, 0x1b, 0xc4, 0xfc, 0xea, 0x91,
+ 0xeb, 0xe8, 0x82, 0xff, 0xa2, 0x58, 0x9a, 0xd0, 0x20, 0xeb, 0xff, 0x7a,
+ 0x17, 0xbb, 0x53, 0x7c, 0xe1, 0xd7, 0xee, 0xe7, 0x13, 0x47, 0x5e, 0x14,
+ 0x96, 0xe7, 0xcb, 0xe3, 0xfb, 0xff, 0x3e, 0x7f, 0x02, 0xe1, 0xc5, 0x0e,
+ 0xa9, 0xd3, 0x0a, 0x94, 0x26, 0xff, 0x33, 0xbf, 0xcf, 0xbe, 0xbd, 0xec,
+ 0x57, 0x3a, 0xff, 0xf2, 0x73, 0xaf, 0x8d, 0x0e, 0x73, 0xf4, 0x3a, 0xfe,
+ 0x53, 0xd1, 0x82, 0xd3, 0xaf, 0xff, 0x46, 0x6f, 0xee, 0xc7, 0x86, 0x3f,
+ 0xd1, 0xd7, 0x47, 0xe7, 0x5d, 0xd5, 0x9d, 0x4d, 0x35, 0x9a, 0x16, 0xa4,
+ 0x46, 0x17, 0x8b, 0x00, 0xeb, 0x7a, 0x74, 0xe1, 0xd7, 0xf0, 0x35, 0xed,
+ 0x67, 0x8e, 0xbf, 0x80, 0xa9, 0x49, 0x91, 0x93, 0xae, 0xce, 0x9d, 0x79,
+ 0x96, 0x59, 0x2a, 0xff, 0xf7, 0x93, 0xda, 0xea, 0x6d, 0xfd, 0xe4, 0x48,
+ 0xa6, 0x0b, 0xfa, 0x51, 0x30, 0xd4, 0x1c, 0x72, 0xdf, 0x19, 0x00, 0xd2,
+ 0xff, 0xff, 0x93, 0xd2, 0x81, 0xcf, 0x75, 0x33, 0xd0, 0xb4, 0xe4, 0x8e,
+ 0xa9, 0x2f, 0x30, 0x85, 0xaf, 0x08, 0x1b, 0x0a, 0x24, 0x21, 0x9a, 0x10,
+ 0xfc, 0x8c, 0xb1, 0x67, 0x1d, 0x36, 0x18, 0xc2, 0xbd, 0x19, 0xe6, 0xc4,
+ 0xab, 0xfe, 0xde, 0x5a, 0xd6, 0x05, 0xfc, 0x75, 0xb0, 0xeb, 0xee, 0x0b,
+ 0xec, 0x3a, 0xa0, 0xfa, 0x94, 0x39, 0x40, 0xfb, 0x39, 0xd7, 0xa3, 0xba,
+ 0x3a, 0xb7, 0x35, 0x48, 0x1f, 0x7f, 0xff, 0x3f, 0x93, 0xae, 0xbf, 0x99,
+ 0xa8, 0xce, 0x60, 0x9d, 0x7f, 0xf9, 0x1b, 0xa8, 0xdb, 0xcf, 0x4a, 0x59,
+ 0xa3, 0xab, 0x88, 0xc4, 0x12, 0x1d, 0x8b, 0x17, 0xdc, 0xee, 0x09, 0xd4,
+ 0x87, 0xa2, 0xe6, 0x37, 0xde, 0x8d, 0xd9, 0x3a, 0xba, 0x78, 0x6c, 0x90,
+ 0x5c, 0xcf, 0x4e, 0xbf, 0xfd, 0x02, 0xdf, 0xbc, 0x7f, 0xd3, 0xdd, 0x83,
+ 0xaf, 0xf2, 0x33, 0xac, 0xc1, 0x9c, 0xeb, 0xe8, 0xd4, 0x6c, 0x3a, 0xff,
+ 0xe8, 0x17, 0xf4, 0xa1, 0x47, 0x67, 0xc7, 0x57, 0x4f, 0x94, 0x04, 0x57,
+ 0xbe, 0x3b, 0x4e, 0xa6, 0xa6, 0x6f, 0xf8, 0xbe, 0x92, 0xbd, 0x09, 0x7d,
+ 0xa2, 0x2b, 0xe5, 0xfd, 0x81, 0x3a, 0xf9, 0x03, 0x8b, 0x3a, 0xf9, 0xdc,
+ 0x7f, 0x3a, 0xcc, 0xc1, 0xe0, 0x28, 0x41, 0x70, 0x16, 0x75, 0xfe, 0x65,
+ 0xe6, 0xc9, 0x42, 0xb9, 0xd4, 0x87, 0xeb, 0xd2, 0x9d, 0x0b, 0x5f, 0xe8,
+ 0x7e, 0x75, 0x97, 0x09, 0x57, 0x32, 0xc9, 0x54, 0x13, 0xca, 0x64, 0xca,
+ 0xf7, 0x91, 0x5c, 0xa6, 0x0d, 0x1d, 0xfd, 0xbb, 0x53, 0x5d, 0x43, 0xaf,
+ 0x81, 0x20, 0x78, 0xea, 0x44, 0xfc, 0x26, 0x86, 0xbe, 0xa1, 0x37, 0xe2,
+ 0xfd, 0xb2, 0xdb, 0x99, 0xd1, 0xd6, 0xc3, 0xad, 0xbe, 0x1a, 0x6f, 0x0b,
+ 0xdf, 0x6f, 0x25, 0x46, 0xe7, 0x5f, 0xfd, 0xad, 0x04, 0x60, 0x3d, 0x8f,
+ 0x68, 0xea, 0x84, 0x49, 0x61, 0x38, 0x0a, 0x2f, 0xfd, 0xe4, 0xe3, 0xff,
+ 0xb5, 0xec, 0xe9, 0xd7, 0xfc, 0x8c, 0x8e, 0x79, 0x01, 0xf9, 0xd7, 0xf9,
+ 0xf9, 0xed, 0x0a, 0x28, 0x75, 0xff, 0xed, 0x62, 0x98, 0x0e, 0x38, 0x63,
+ 0xb0, 0x75, 0x49, 0x32, 0x14, 0x2e, 0x57, 0x41, 0x73, 0x8d, 0x19, 0x5e,
+ 0xc4, 0xe1, 0xd7, 0xfa, 0x48, 0xbe, 0xee, 0xea, 0xe7, 0x5f, 0x3f, 0x22,
+ 0x47, 0x5f, 0xf3, 0xef, 0xf3, 0x7d, 0x60, 0xa8, 0x75, 0x4e, 0x8a, 0xcd,
+ 0xc6, 0x96, 0x6d, 0xe2, 0x0b, 0xee, 0xab, 0xa2, 0xce, 0xbc, 0x31, 0xf9,
+ 0xd7, 0xa1, 0x79, 0xf0, 0xdf, 0xe8, 0x92, 0xff, 0xd1, 0xbf, 0x61, 0x6d,
+ 0xea, 0x4c, 0x75, 0x62, 0x3c, 0x11, 0xfb, 0x86, 0x77, 0xe6, 0xbc, 0xf8,
+ 0xc9, 0xd7, 0xe8, 0xe0, 0x70, 0x4e, 0xa1, 0x3c, 0xdf, 0x14, 0x5f, 0xfd,
+ 0x1f, 0xc7, 0x56, 0x2e, 0xa7, 0x50, 0xeb, 0x2a, 0x8e, 0xbf, 0xc1, 0xec,
+ 0x0b, 0x2f, 0xb9, 0xd7, 0xff, 0x20, 0x7b, 0x0d, 0x8f, 0xdc, 0x7f, 0x3a,
+ 0xff, 0xff, 0x96, 0xe3, 0xbc, 0x98, 0x67, 0x13, 0x66, 0x0e, 0x05, 0xe4,
+ 0x78, 0xbd, 0x6f, 0xca, 0x79, 0xdc, 0x4e, 0xbc, 0x20, 0x9c, 0xea, 0x73,
+ 0xc2, 0xf1, 0x35, 0x22, 0x35, 0xc6, 0x16, 0xd5, 0x09, 0xf5, 0xf0, 0x85,
+ 0x68, 0x6e, 0x29, 0xa3, 0x30, 0x46, 0x35, 0x72, 0xb0, 0xad, 0x9d, 0x79,
+ 0x23, 0x87, 0x52, 0xa8, 0xdd, 0x74, 0x82, 0xff, 0xee, 0x22, 0xe1, 0x5c,
+ 0x71, 0x7b, 0xc1, 0xd5, 0x23, 0xea, 0x98, 0x96, 0xf9, 0x05, 0xc2, 0x75,
+ 0xe9, 0xd6, 0x87, 0x50, 0x4d, 0xd8, 0x8f, 0xdf, 0xa5, 0x9b, 0x22, 0x47,
+ 0x5e, 0xce, 0x41, 0xd5, 0xba, 0x30, 0x11, 0x7b, 0x84, 0x1d, 0x28, 0xbf,
+ 0xfe, 0xcf, 0x6b, 0x26, 0xec, 0x6c, 0xce, 0xf6, 0x0e, 0xbf, 0xff, 0xff,
+ 0x26, 0x6f, 0xa4, 0xc6, 0x7e, 0x66, 0xf2, 0xd2, 0x7b, 0x49, 0xb8, 0x42,
+ 0x09, 0xce, 0xbf, 0xff, 0x20, 0x87, 0xe7, 0xdf, 0x26, 0x9d, 0x04, 0x12,
+ 0x3a, 0x85, 0x32, 0xef, 0x28, 0x6c, 0x84, 0x45, 0xe0, 0x72, 0x47, 0x5f,
+ 0xcf, 0xef, 0xfe, 0x8c, 0x8e, 0xaf, 0x87, 0x97, 0x38, 0xe5, 0xfe, 0x89,
+ 0x23, 0x0c, 0xb2, 0xc9, 0x57, 0x94, 0xc0, 0x9d, 0x7f, 0x75, 0xf8, 0xd8,
+ 0xf1, 0xd7, 0x38, 0x4e, 0xbf, 0xb8, 0xfa, 0xeb, 0xc8, 0xeb, 0x6e, 0x75,
+ 0xc8, 0xc9, 0xd7, 0x7d, 0xfc, 0xea, 0x98, 0xd7, 0xfe, 0x2d, 0x7a, 0x4e,
+ 0x13, 0xae, 0x65, 0x93, 0xaa, 0x48, 0xd7, 0xc1, 0x56, 0x96, 0x22, 0x06,
+ 0x88, 0xd9, 0x1b, 0xbd, 0xef, 0xbf, 0x94, 0xc1, 0xeb, 0x5f, 0xf2, 0x07,
+ 0x16, 0x93, 0x23, 0x27, 0x5f, 0xfe, 0x70, 0xe6, 0x0a, 0x9a, 0xd6, 0x0f,
+ 0xe7, 0x5f, 0x74, 0x0e, 0xa4, 0x22, 0x01, 0x67, 0x17, 0xff, 0xf4, 0x9f,
+ 0x5a, 0x8c, 0x9c, 0x12, 0x0f, 0x05, 0xd9, 0x3a, 0xef, 0x40, 0x51, 0x2a,
+ 0x87, 0x57, 0xed, 0x3c, 0xfa, 0xe9, 0xd5, 0x25, 0x62, 0x01, 0x1c, 0xde,
+ 0x35, 0x94, 0x8d, 0x1b, 0xc5, 0xb7, 0xed, 0x9f, 0x7a, 0x9e, 0x3a, 0xff,
+ 0xb3, 0xdd, 0x8e, 0x7b, 0x1a, 0x75, 0xe8, 0xe4, 0xc7, 0x54, 0x2f, 0x17,
+ 0x64, 0x6d, 0x69, 0x08, 0x2e, 0x92, 0xbc, 0xb4, 0x6f, 0xd6, 0x04, 0xaf,
+ 0x6c, 0xde, 0xf6, 0x9e, 0x63, 0xaf, 0xfe, 0x40, 0xbf, 0x93, 0x59, 0x2c,
+ 0xe9, 0xd7, 0x3e, 0xd1, 0xd6, 0xce, 0x9e, 0xcf, 0x90, 0x6b, 0x74, 0x4e,
+ 0x0b, 0xad, 0xf6, 0x6f, 0x3e, 0xc3, 0xaf, 0xf8, 0x43, 0x82, 0x09, 0x66,
+ 0x8e, 0xbf, 0xdf, 0x7c, 0x39, 0x3a, 0x70, 0xeb, 0xef, 0x26, 0x90, 0xea,
+ 0xe2, 0x2b, 0xdc, 0x94, 0x4d, 0x80, 0x69, 0x7f, 0xdd, 0x40, 0xa2, 0xa6,
+ 0x05, 0x0e, 0xbf, 0xcf, 0x2c, 0x0f, 0x35, 0xa3, 0xaf, 0xa3, 0x3e, 0x84,
+ 0xeb, 0xfc, 0xa2, 0x79, 0xfa, 0xca, 0xb9, 0xd7, 0xfd, 0xcc, 0x9b, 0xb9,
+ 0xa7, 0x13, 0xaf, 0xfb, 0xb9, 0x2c, 0x02, 0xa5, 0xc4, 0xeb, 0xff, 0xfc,
+ 0x83, 0x9b, 0xf9, 0x47, 0xf7, 0x63, 0xb9, 0xb1, 0xe4, 0x75, 0x05, 0x35,
+ 0xd6, 0x99, 0x21, 0x17, 0x0d, 0xfc, 0x6f, 0xb0, 0xea, 0xff, 0x82, 0x9c,
+ 0x8d, 0x9f, 0xea, 0x47, 0x5d, 0x0b, 0x3a, 0xde, 0x83, 0xd0, 0xe9, 0xdd,
+ 0xff, 0xa3, 0x4f, 0xd4, 0x0b, 0x52, 0x73, 0xaa, 0x15, 0x51, 0xe4, 0x72,
+ 0xcf, 0x0a, 0x90, 0x13, 0xde, 0x81, 0xf1, 0xd7, 0xf9, 0x3a, 0x9c, 0x94,
+ 0xd0, 0x75, 0xff, 0xf9, 0x00, 0xdf, 0xbb, 0xfe, 0xfa, 0x7e, 0x26, 0xff,
+ 0x9d, 0x7c, 0xfc, 0x89, 0x1d, 0x7f, 0xff, 0x20, 0xba, 0x0f, 0xfc, 0x8e,
+ 0xba, 0x7a, 0x3a, 0x75, 0x09, 0xfb, 0x78, 0x82, 0xfc, 0x9e, 0xd0, 0x27,
+ 0x3a, 0xff, 0xfa, 0x05, 0x3f, 0xf6, 0xed, 0x4e, 0x7d, 0x80, 0x9d, 0x41,
+ 0x4d, 0xa9, 0x21, 0xa0, 0xb2, 0x1f, 0x14, 0x5f, 0xb8, 0x06, 0xf6, 0x0e,
+ 0xbf, 0xb9, 0x34, 0x93, 0xda, 0x3a, 0xc3, 0x07, 0xab, 0x84, 0xf7, 0xfa,
+ 0x67, 0x99, 0xf7, 0x96, 0x8e, 0xbf, 0x9e, 0x74, 0x99, 0x19, 0x3a, 0xb0,
+ 0xf8, 0xdc, 0xd6, 0xfe, 0x9f, 0x06, 0x7c, 0x64, 0xeb, 0xfe, 0x89, 0xfe,
+ 0xcb, 0xa0, 0x79, 0xce, 0xac, 0x3e, 0xae, 0x17, 0x5f, 0xa3, 0x9c, 0xce,
+ 0x9d, 0x7f, 0x0b, 0xa9, 0x0b, 0x83, 0xaa, 0x47, 0xa2, 0x02, 0x6b, 0xe8,
+ 0x9d, 0x45, 0x0e, 0xbf, 0xff, 0x23, 0x61, 0x7a, 0x7e, 0x62, 0xc0, 0xd7,
+ 0x91, 0xd7, 0x26, 0xc3, 0xad, 0xd3, 0xaa, 0x47, 0xf4, 0xae, 0xa6, 0x01,
+ 0x7b, 0xc1, 0x85, 0x9d, 0x7f, 0xb3, 0xfc, 0x9a, 0x37, 0xd1, 0xd5, 0x07,
+ 0x9f, 0x83, 0x77, 0xf7, 0x5e, 0x51, 0xa9, 0x1d, 0x7f, 0xd9, 0xd4, 0xdf,
+ 0x5d, 0x06, 0x8e, 0xbb, 0x05, 0xa7, 0xcb, 0xf9, 0x65, 0xfc, 0x2f, 0xf8,
+ 0x70, 0x4e, 0xbf, 0x26, 0xde, 0x71, 0x43, 0xae, 0x52, 0x47, 0x5f, 0xba,
+ 0x9b, 0x11, 0xa7, 0x5d, 0x9d, 0x91, 0xbf, 0x68, 0xbd, 0x2d, 0x12, 0xbb,
+ 0x6d, 0x37, 0x99, 0x65, 0x92, 0xaf, 0xfd, 0xc1, 0x03, 0xfd, 0xc9, 0xa1,
+ 0x67, 0x30, 0x5f, 0xdf, 0xba, 0x93, 0x23, 0x27, 0x54, 0x1f, 0xbe, 0x27,
+ 0xdf, 0xe8, 0x0e, 0x4a, 0x05, 0xa7, 0x54, 0x2f, 0xc8, 0x48, 0x6b, 0x23,
+ 0x9c, 0x57, 0x84, 0xbc, 0xd0, 0x88, 0xe4, 0x22, 0x96, 0xe5, 0xd2, 0x27,
+ 0x84, 0xf0, 0xc2, 0x07, 0x50, 0x85, 0xf1, 0x68, 0x21, 0x80, 0xcc, 0x2f,
+ 0x3e, 0x90, 0x5f, 0x73, 0x99, 0xd3, 0xaf, 0xee, 0xa6, 0xd6, 0xd0, 0x14,
+ 0x3a, 0xa0, 0xf5, 0x5a, 0x43, 0x65, 0x49, 0xd6, 0x43, 0xaf, 0xfb, 0xd1,
+ 0xcd, 0x76, 0x07, 0xc7, 0x59, 0x52, 0x75, 0xff, 0x7a, 0x39, 0xae, 0xc0,
+ 0xf8, 0xeb, 0xb5, 0x07, 0x5e, 0x58, 0x60, 0xeb, 0xfc, 0x3e, 0x79, 0xb5,
+ 0x1e, 0x3a, 0x90, 0xf3, 0x5c, 0x6e, 0xf9, 0x1f, 0x1a, 0x75, 0xff, 0xb3,
+ 0x60, 0xe6, 0xa6, 0x18, 0x09, 0xd7, 0xcd, 0x0c, 0x4e, 0x75, 0xdf, 0xc1,
+ 0xd7, 0xb4, 0x9c, 0x3a, 0xb0, 0xf4, 0xff, 0x22, 0xf0, 0xb5, 0xfe, 0x96,
+ 0x0a, 0x07, 0x04, 0xeb, 0xde, 0xd3, 0x10, 0x9e, 0xde, 0x0a, 0x4c, 0x6f,
+ 0xd6, 0x2f, 0xc8, 0x04, 0x7f, 0x50, 0x91, 0xf1, 0x7d, 0xda, 0x83, 0xaf,
+ 0x2c, 0x30, 0x75, 0xfe, 0x1f, 0x3c, 0xda, 0x8f, 0x1d, 0x48, 0x79, 0xae,
+ 0x37, 0x7c, 0x8f, 0x8d, 0x3a, 0xff, 0xd9, 0xb0, 0x73, 0x53, 0x0c, 0x04,
+ 0xeb, 0xe6, 0x86, 0x27, 0x3a, 0xfe, 0x9b, 0xf4, 0x57, 0x79, 0x8e, 0xbb,
+ 0xf8, 0x3a, 0xf6, 0x93, 0x87, 0x56, 0x22, 0x15, 0xa4, 0x5f, 0x99, 0x78,
+ 0x5a, 0xff, 0x4b, 0x05, 0x03, 0x82, 0x75, 0xfc, 0x2e, 0x1c, 0x51, 0x88,
+ 0x5c, 0x8e, 0x08, 0xa6, 0x07, 0xb6, 0x50, 0x94, 0xd0, 0x89, 0xeb, 0x17,
+ 0xe4, 0x02, 0x3f, 0xa8, 0x61, 0xf8, 0xf6, 0xff, 0xee, 0x46, 0xfa, 0x18,
+ 0x5e, 0x6f, 0xe3, 0xaf, 0xff, 0xce, 0x1c, 0xc1, 0x53, 0xe8, 0xc0, 0xce,
+ 0x9c, 0x3a, 0xf3, 0xf2, 0x73, 0xc8, 0x25, 0x7d, 0x2c, 0xde, 0x47, 0x90,
+ 0x4a, 0xf6, 0x90, 0x27, 0x90, 0x4a, 0xe6, 0x59, 0x3c, 0x82, 0x54, 0xd4,
+ 0x52, 0xcc, 0x53, 0xe2, 0xf6, 0x4a, 0x2e, 0x7f, 0x16, 0x41, 0x23, 0x06,
+ 0xfe, 0xfe, 0xce, 0xe6, 0x0a, 0x87, 0x5e, 0x71, 0xff, 0xe2, 0xfa, 0x5c,
+ 0x4e, 0x57, 0xf2, 0x18, 0x2b, 0x44, 0x18, 0xce, 0x3c, 0x69, 0x7d, 0xb7,
+ 0x8f, 0xd3, 0xad, 0x8a, 0xe8, 0xa1, 0xfd, 0xfa, 0xd2, 0x3a, 0xff, 0x4d,
+ 0x20, 0x4f, 0xe4, 0x9c, 0xab, 0x41, 0xd7, 0xf9, 0x24, 0x07, 0xd7, 0x50,
+ 0xeb, 0xfb, 0x36, 0x3a, 0xf3, 0xa7, 0x5a, 0x45, 0x5e, 0x7e, 0x4e, 0x55,
+ 0x15, 0x50, 0x6d, 0x9a, 0x20, 0xb1, 0xcb, 0xd1, 0xfb, 0x4a, 0x60, 0xd6,
+ 0xd2, 0xd1, 0x7a, 0x30, 0x90, 0xa8, 0x4c, 0x57, 0x21, 0xdd, 0x7f, 0xfd,
+ 0xf4, 0x65, 0xae, 0x87, 0x39, 0xfa, 0xd3, 0x47, 0x5f, 0x01, 0xf9, 0x23,
+ 0xac, 0xb3, 0xae, 0xc9, 0x04, 0xd8, 0xcc, 0x43, 0x7e, 0x67, 0x26, 0x45,
+ 0x9d, 0x7f, 0x36, 0x26, 0x94, 0x7e, 0x55, 0x90, 0xeb, 0xfe, 0x9c, 0x12,
+ 0x0f, 0x40, 0xe2, 0x75, 0xfc, 0x90, 0xb9, 0xf1, 0x93, 0xaf, 0xd9, 0x3a,
+ 0xf1, 0x67, 0x5e, 0xd2, 0x70, 0xea, 0x13, 0xc2, 0xf1, 0x3d, 0xfc, 0x2f,
+ 0xff, 0xe0, 0xd1, 0xd7, 0xf2, 0x29, 0xf6, 0x16, 0xc0, 0x53, 0x06, 0xc0,
+ 0xfe, 0x1c, 0xe9, 0xbf, 0xc4, 0x35, 0x89, 0xe6, 0x21, 0x40, 0xc6, 0x69,
+ 0x7c, 0x39, 0x38, 0x0e, 0xbf, 0xec, 0xf7, 0xc1, 0xcf, 0xfe, 0xee, 0x75,
+ 0x49, 0x73, 0x2c, 0x25, 0x98, 0x21, 0xc3, 0x6e, 0xc6, 0x49, 0xf9, 0x38,
+ 0xc2, 0x0f, 0x51, 0xfc, 0xf8, 0xd3, 0x6c, 0x86, 0xff, 0xfd, 0x3f, 0x39,
+ 0x81, 0x75, 0xf5, 0xfc, 0x31, 0x31, 0xd7, 0xff, 0xff, 0x81, 0xc0, 0x4c,
+ 0x2f, 0xfe, 0xb5, 0x8a, 0x60, 0x38, 0xe1, 0x8e, 0xc1, 0xd7, 0xdb, 0x5d,
+ 0x07, 0xd3, 0xaf, 0x32, 0xcb, 0x25, 0x5d, 0x28, 0x29, 0x82, 0xfe, 0xa1,
+ 0x33, 0x89, 0xd5, 0x77, 0x78, 0xe2, 0x35, 0xfc, 0xa4, 0x73, 0x99, 0xd3,
+ 0xaf, 0xe9, 0xe6, 0x92, 0xab, 0x93, 0x9d, 0x7d, 0xd7, 0xdd, 0x93, 0xaf,
+ 0xd3, 0xf1, 0x21, 0x67, 0x5f, 0xff, 0x47, 0xdf, 0x0c, 0x7e, 0xfe, 0xff,
+ 0xe8, 0xc8, 0xea, 0x56, 0x51, 0xa4, 0x86, 0xae, 0x47, 0xe2, 0x7b, 0xff,
+ 0x3f, 0xb4, 0xce, 0x77, 0xf7, 0xf1, 0xd7, 0xff, 0xfe, 0xcf, 0x43, 0x47,
+ 0x30, 0x62, 0x5e, 0xeb, 0xac, 0x73, 0x61, 0xd4, 0x14, 0x53, 0xb2, 0x7f,
+ 0x7b, 0xe8, 0x66, 0x3a, 0xf4, 0x90, 0x4e, 0xbe, 0x9f, 0xee, 0xd3, 0x27,
+ 0x5f, 0xf4, 0x75, 0xd3, 0xd3, 0x23, 0x27, 0x5f, 0xfe, 0x52, 0x35, 0xc8,
+ 0xe8, 0xe7, 0xa1, 0x67, 0x5f, 0xf6, 0x87, 0x36, 0x24, 0xc8, 0xc9, 0xd7,
+ 0xff, 0xf0, 0x1e, 0x76, 0x82, 0x7f, 0x67, 0x47, 0x3d, 0xd4, 0x3a, 0xfd,
+ 0x13, 0x08, 0x34, 0x75, 0x62, 0x60, 0x88, 0x91, 0xd3, 0xaf, 0x2d, 0xdc,
+ 0x82, 0x75, 0xfc, 0xe3, 0xfe, 0x79, 0x43, 0xaa, 0x15, 0x1f, 0xce, 0x49,
+ 0x21, 0xf7, 0x1a, 0x12, 0x9f, 0x46, 0x79, 0xb0, 0xf3, 0x6c, 0x52, 0xfb,
+ 0xa0, 0x5c, 0x1d, 0x73, 0xe8, 0xeb, 0x80, 0xa9, 0x3a, 0x9c, 0xf4, 0x04,
+ 0x84, 0x02, 0xb7, 0x3b, 0x0a, 0x87, 0xca, 0x86, 0x56, 0xdb, 0x15, 0x50,
+ 0x93, 0x56, 0x85, 0x6a, 0xd4, 0x8d, 0x57, 0x1d, 0xc4, 0xe1, 0x4c, 0xf2,
+ 0x81, 0xe5, 0x0d, 0xb0, 0xca, 0xa4, 0xca, 0x43, 0xe2, 0x91, 0x97, 0x36,
+ 0x3b, 0x0d, 0xe3, 0x5a, 0x49, 0x48, 0x93, 0x4a, 0x31, 0xe4, 0x7d, 0x0b,
+ 0x94, 0xcd, 0xd9, 0xfe, 0xe7, 0x8c, 0x87, 0xf8, 0x69, 0x0c, 0xad, 0xed,
+ 0x4f, 0xeb, 0xfa, 0x9c, 0x18, 0x08, 0xf6, 0x59, 0x3f, 0xdb, 0x87, 0xff,
+ 0xd9, 0x64, 0xdb, 0x50, 0xcc, 0xbf, 0x2f, 0x11, 0xff, 0x3a, 0xf9, 0xae,
+ 0xed, 0x34, 0x51, 0x57, 0xff, 0xe7, 0xfe, 0x1b, 0xd4, 0xd7, 0x53, 0xdd,
+ 0xc1, 0x3a, 0xb8, 0x88, 0x01, 0x2d, 0xbf, 0x30, 0xb7, 0x93, 0x10, 0x8c,
+ 0x8c, 0x85, 0x35, 0xfe, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x2e, 0x8b, 0xff,
+ 0x98, 0x79, 0x31, 0x9c, 0x6b, 0xbb, 0x4d, 0x12, 0x5d, 0xfb, 0x8d, 0x77,
+ 0x69, 0xa2, 0xf2, 0xb9, 0xf6, 0x1d, 0x66, 0x30, 0xf2, 0xb6, 0xcc, 0xea,
+ 0x1f, 0x50, 0x3a, 0x72, 0x89, 0x1f, 0xe4, 0x26, 0x1b, 0x09, 0x59, 0x8e,
+ 0x16, 0x7f, 0xd9, 0x52, 0x23, 0x79, 0x61, 0x7a, 0x96, 0x3b, 0xe4, 0x50,
+ 0x1f, 0xec, 0x84, 0xdd, 0xff, 0xe6, 0x16, 0xf2, 0x63, 0x38, 0xd7, 0x76,
+ 0x9a, 0x25, 0x9b, 0x81, 0xd3, 0xaf, 0xf2, 0x07, 0xb8, 0x82, 0xa1, 0xd7,
+ 0xdd, 0x7f, 0x00, 0xeb, 0xee, 0xc2, 0xba, 0xce, 0xbc, 0x06, 0xb9, 0xd5,
+ 0x24, 0x48, 0xa1, 0x8a, 0xb9, 0x0f, 0xd2, 0x4b, 0xf8, 0x3e, 0x03, 0xcb,
+ 0x47, 0x5e, 0xf3, 0xac, 0xeb, 0xff, 0x76, 0x3a, 0x8a, 0x7b, 0x4f, 0xf9,
+ 0xd7, 0xf0, 0xfb, 0x90, 0xed, 0x3a, 0xf9, 0xae, 0xed, 0x34, 0x46, 0x77,
+ 0xf2, 0x42, 0xe7, 0xc6, 0x4e, 0xb8, 0x64, 0x75, 0x96, 0x75, 0xf9, 0x39,
+ 0xd7, 0x63, 0x87, 0xa4, 0xb2, 0xdf, 0xa2, 0xb7, 0xf3, 0xc9, 0x38, 0xfc,
+ 0x3a, 0xff, 0xed, 0x20, 0x35, 0x82, 0x09, 0x66, 0x8e, 0xbd, 0xa8, 0xdc,
+ 0xea, 0x92, 0x78, 0x18, 0x7f, 0xc2, 0xb5, 0xbf, 0x8a, 0x76, 0x8a, 0xfc,
+ 0x85, 0x7f, 0xdc, 0x76, 0x7a, 0x91, 0xc8, 0x3a, 0xff, 0xa5, 0xac, 0x8f,
+ 0x91, 0xa5, 0x9d, 0x7d, 0xbf, 0x63, 0x47, 0x5f, 0x6a, 0x3d, 0xa3, 0xab,
+ 0x0f, 0x0f, 0x44, 0x57, 0xff, 0x79, 0x38, 0xff, 0xfc, 0xde, 0x50, 0xb3,
+ 0xaf, 0xc3, 0x12, 0xd3, 0x9d, 0x48, 0x7d, 0x9b, 0x11, 0xef, 0xff, 0xff,
+ 0xb3, 0xde, 0x45, 0xf1, 0x33, 0x71, 0x07, 0xa3, 0xbf, 0x36, 0x27, 0xa6,
+ 0x83, 0xaf, 0xf3, 0xcb, 0x5a, 0x71, 0x91, 0xd7, 0xe5, 0x3d, 0xe8, 0x59,
+ 0xd7, 0xff, 0xbd, 0x0d, 0x4f, 0x22, 0xe6, 0xd2, 0x09, 0xd6, 0x91, 0xd4,
+ 0x87, 0xb1, 0xf5, 0x22, 0xfd, 0xfc, 0x7a, 0x02, 0x75, 0x22, 0x32, 0x9e,
+ 0x10, 0x00, 0x23, 0xbf, 0xfe, 0x07, 0xb5, 0xbc, 0xa0, 0x7f, 0xd7, 0xc0,
+ 0x09, 0xd7, 0xa3, 0xd0, 0x75, 0x04, 0xfb, 0x76, 0x29, 0xde, 0xee, 0x09,
+ 0xd4, 0x86, 0xf8, 0x04, 0x97, 0x76, 0x63, 0xaf, 0xf6, 0xfa, 0x1c, 0xe0,
+ 0x60, 0xea, 0x43, 0xc9, 0x71, 0x7b, 0xef, 0x74, 0x1b, 0x67, 0x5f, 0xec,
+ 0x8e, 0x3c, 0x93, 0xa7, 0x5f, 0xe4, 0x67, 0x51, 0xd7, 0x57, 0x3a, 0xb8,
+ 0x7c, 0xbe, 0x30, 0xa4, 0x45, 0x62, 0xe1, 0x15, 0x7f, 0xf9, 0x3a, 0x05,
+ 0x70, 0xf4, 0x1a, 0xde, 0x4e, 0x75, 0x61, 0xfa, 0xb9, 0x3d, 0xef, 0xb8,
+ 0xaa, 0x3a, 0xff, 0xf0, 0x3f, 0x5a, 0x0e, 0x7e, 0x38, 0xf3, 0x1d, 0x7f,
+ 0xd0, 0x9d, 0x48, 0x19, 0x80, 0x75, 0xff, 0x80, 0x1e, 0x60, 0x3b, 0x0b,
+ 0xc3, 0xab, 0x11, 0xbb, 0xc2, 0x1e, 0xa4, 0xe8, 0xda, 0xff, 0xfb, 0x79,
+ 0x27, 0x03, 0xd0, 0x73, 0x1b, 0xdc, 0x3a, 0xe4, 0x64, 0xeb, 0xb6, 0xb0,
+ 0xea, 0xd1, 0xae, 0xf0, 0xb5, 0xfd, 0xa8, 0xf6, 0xba, 0x87, 0x5f, 0x87,
+ 0x17, 0xcc, 0x3a, 0xfb, 0x9b, 0x30, 0x27, 0x56, 0x1f, 0xa2, 0xcb, 0x00,
+ 0x4b, 0x7d, 0xfa, 0x6f, 0x23, 0xaf, 0xf4, 0x0f, 0x92, 0x71, 0x83, 0xaf,
+ 0xff, 0x27, 0x12, 0x78, 0x1c, 0xef, 0x01, 0xb0, 0xea, 0xfd, 0x13, 0xa2,
+ 0x47, 0xe3, 0x0b, 0x30, 0xad, 0xb3, 0x00, 0x22, 0x14, 0xf3, 0xa0, 0x84,
+ 0xb7, 0x23, 0xdb, 0x51, 0x8f, 0x73, 0x74, 0x7c, 0x9a, 0x11, 0xbc, 0x23,
+ 0x5c, 0x20, 0x3b, 0x0f, 0xb7, 0x86, 0xf7, 0xed, 0x23, 0x1a, 0x0e, 0xa1,
+ 0xfb, 0xe3, 0xcd, 0x8f, 0xdb, 0x70, 0x95, 0xfb, 0x0c, 0xbb, 0xff, 0xcc,
+ 0x2d, 0xe4, 0xc6, 0x71, 0xae, 0xed, 0x34, 0x4d, 0x37, 0xff, 0x98, 0x5b,
+ 0xc9, 0x8c, 0xe3, 0x5d, 0xda, 0x68, 0x9c, 0x6f, 0xff, 0x30, 0xb7, 0x93,
+ 0x19, 0xc6, 0xbb, 0xb4, 0xd1, 0x40, 0xdf, 0xb8, 0xd7, 0x76, 0x9a, 0x2e,
+ 0x0b, 0xf8, 0x73, 0xcd, 0x4d, 0x1d, 0x74, 0x21, 0xd7, 0xf8, 0x65, 0x08,
+ 0x1c, 0x59, 0xd5, 0x88, 0xa2, 0x59, 0x9f, 0x4a, 0xc0, 0x29, 0x7e, 0x93,
+ 0x0a, 0x2a, 0x14, 0x3a, 0x98, 0x3e, 0xb8, 0x3c, 0xb9, 0xff, 0x3a, 0xfd,
+ 0x34, 0xa0, 0x64, 0x75, 0x1d, 0x58, 0x6c, 0x44, 0x9e, 0xfa, 0x3f, 0xc6,
+ 0x4e, 0xb9, 0x18, 0xe2, 0x22, 0x05, 0x1f, 0xe8, 0xfd, 0xff, 0x49, 0x8c,
+ 0xe3, 0x5d, 0xda, 0x68, 0x92, 0x6c, 0xc7, 0x51, 0x04, 0xe7, 0xb7, 0x33,
+ 0xf9, 0xd7, 0xf9, 0xfc, 0x39, 0x3b, 0x89, 0xd7, 0xf6, 0x0b, 0xef, 0x2d,
+ 0x1d, 0x7f, 0x42, 0xf9, 0x81, 0xf1, 0xd7, 0x3b, 0x01, 0x45, 0x02, 0x83,
+ 0x1c, 0x30, 0xd1, 0x65, 0x4e, 0xd9, 0x00, 0x4a, 0x98, 0xae, 0xd8, 0xd6,
+ 0x26, 0x57, 0xfd, 0x5f, 0x51, 0xb2, 0x7a, 0x32, 0xcd, 0x90, 0xc9, 0xbf,
+ 0xf2, 0x8e, 0xc6, 0x71, 0xae, 0xed, 0x34, 0x5a, 0x97, 0xfe, 0x79, 0x31,
+ 0x9c, 0x6b, 0xbb, 0x4d, 0x12, 0xad, 0xc8, 0xc9, 0xd4, 0x75, 0x98, 0x51,
+ 0x16, 0xab, 0x4b, 0xf2, 0x56, 0xd0, 0xb5, 0xfd, 0x9c, 0x6b, 0xbb, 0x4d,
+ 0x11, 0x4d, 0xff, 0xcb, 0x63, 0xc2, 0xff, 0xeb, 0xd8, 0xd3, 0xa9, 0x83,
+ 0xfd, 0x73, 0x8b, 0xfc, 0xc6, 0x71, 0xae, 0xed, 0x34, 0x46, 0x97, 0x03,
+ 0xa7, 0x5f, 0xf8, 0x38, 0xb4, 0xe6, 0x6a, 0x68, 0x3a, 0xff, 0xff, 0x9c,
+ 0x1a, 0xee, 0x07, 0xef, 0xdd, 0x27, 0xdf, 0x26, 0xa6, 0xfa, 0x75, 0xe4,
+ 0x76, 0x4e, 0xa4, 0x46, 0x3a, 0xb9, 0xea, 0xdb, 0xef, 0x9a, 0xee, 0xd3,
+ 0x45, 0x3f, 0x77, 0xa0, 0xea, 0xe1, 0xe1, 0x78, 0xb6, 0xff, 0xde, 0x9a,
+ 0x3d, 0xd7, 0x9b, 0xe6, 0x1d, 0x7f, 0xf9, 0x16, 0x20, 0xea, 0x73, 0x35,
+ 0x34, 0x1d, 0x7f, 0xf0, 0x3d, 0xc0, 0x4d, 0xa6, 0xbc, 0xda, 0x3a, 0xff,
+ 0xec, 0x98, 0x03, 0x3e, 0x9a, 0xf3, 0x68, 0xeb, 0x30, 0xad, 0xaa, 0x89,
+ 0x88, 0x6e, 0xe3, 0xa2, 0x11, 0x3a, 0x08, 0xa4, 0x79, 0x1e, 0xff, 0xf3,
+ 0x0b, 0x79, 0x31, 0x9c, 0x6b, 0xbb, 0x4d, 0x13, 0x55, 0xfe, 0x63, 0x38,
+ 0xd7, 0x76, 0x9a, 0x2b, 0xbb, 0xe6, 0xbb, 0xb4, 0xd1, 0x5f, 0x5e, 0x65,
+ 0x96, 0x4a, 0xb0, 0x94, 0xc1, 0x7f, 0x5c, 0x3e, 0xb5, 0xa6, 0x5e, 0x94,
+ 0x6e, 0x75, 0xe9, 0xb3, 0xa7, 0x5f, 0xfb, 0x3a, 0xcb, 0xfb, 0x51, 0x93,
+ 0x9d, 0x6f, 0x1d, 0x7f, 0xc9, 0xcc, 0x9d, 0x25, 0x81, 0x3a, 0xb8, 0x78,
+ 0xee, 0x21, 0x7e, 0xdf, 0x6b, 0xa0, 0xfa, 0x75, 0xb8, 0x75, 0x1d, 0x6e,
+ 0xa1, 0x75, 0xc1, 0x0b, 0x31, 0x89, 0xb6, 0xcc, 0x44, 0xe3, 0x82, 0x39,
+ 0xa8, 0x42, 0x80, 0x87, 0x6d, 0x22, 0xff, 0xf3, 0x0b, 0x79, 0x31, 0x9c,
+ 0x6b, 0xbb, 0x4d, 0x13, 0xdd, 0xfb, 0xb1, 0xb4, 0xfb, 0x9d, 0x7e, 0xe3,
+ 0x5d, 0xda, 0x68, 0xb8, 0x6c, 0xc4, 0x1e, 0xee, 0x15, 0x5f, 0xfc, 0xc3,
+ 0xc9, 0x8c, 0xe3, 0x5d, 0xda, 0x68, 0x93, 0xea, 0x19, 0x05, 0xb3, 0xc3,
+ 0x16, 0x44, 0x4a, 0x4a, 0xc8, 0x6b, 0x94, 0xca, 0xfc, 0x94, 0x2f, 0xd7,
+ 0x2d, 0x42, 0xd3, 0x61, 0x3d, 0xfe, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x22,
+ 0xab, 0xf7, 0x1a, 0xee, 0xd3, 0x45, 0x33, 0x7f, 0x27, 0x71, 0xf7, 0xfc,
+ 0xeb, 0x31, 0x87, 0xc1, 0xb6, 0x67, 0x7f, 0xf9, 0x85, 0xbc, 0x98, 0xce,
+ 0x35, 0xdd, 0xa6, 0x89, 0x9e, 0xff, 0xf3, 0x0b, 0x79, 0x31, 0x9c, 0x6b,
+ 0xbb, 0x4d, 0x14, 0x6d, 0x4e, 0x9b, 0xc0, 0x61, 0x3e, 0xa1, 0x5f, 0x95,
+ 0xef, 0xfc, 0xf2, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x23, 0xab, 0xff, 0xb9,
+ 0x3b, 0x1a, 0x1c, 0xf6, 0xa1, 0x67, 0x53, 0x08, 0x8f, 0x84, 0xab, 0x81,
+ 0xd3, 0xaf, 0x9a, 0xd0, 0x34, 0xeb, 0xf6, 0x08, 0x72, 0x73, 0xaf, 0xf4,
+ 0x43, 0x73, 0x9c, 0xc3, 0xa9, 0x0f, 0x58, 0x49, 0xaf, 0xd9, 0xc6, 0x81,
+ 0x43, 0xaf, 0xfc, 0x38, 0xa3, 0xcd, 0xae, 0xc0, 0x4e, 0xbd, 0x33, 0xf8,
+ 0xeb, 0xe6, 0xbb, 0xb4, 0xd1, 0x4d, 0x5f, 0xb3, 0x76, 0x5f, 0xa7, 0x5f,
+ 0xfd, 0xac, 0x10, 0xc7, 0xc5, 0x5f, 0xb3, 0xf4, 0x3a, 0x82, 0x99, 0x22,
+ 0x14, 0x4c, 0x7d, 0xc1, 0xc1, 0x2d, 0xd1, 0x45, 0xff, 0xff, 0x60, 0xfb,
+ 0x48, 0xdc, 0x1d, 0x37, 0xa9, 0xd6, 0xfd, 0x9c, 0xeb, 0xfe, 0xd3, 0xef,
+ 0x93, 0x47, 0x74, 0x75, 0xdd, 0x41, 0x45, 0x07, 0x99, 0xef, 0xfe, 0x97,
+ 0x50, 0x67, 0xd0, 0x23, 0x93, 0x1d, 0x7f, 0xda, 0xd3, 0x53, 0x9c, 0x49,
+ 0xce, 0xbf, 0xf6, 0x32, 0xff, 0xbf, 0xbd, 0x9d, 0x3a, 0xff, 0xc2, 0x0f,
+ 0x77, 0x26, 0x94, 0x6e, 0x75, 0xa6, 0x3a, 0xfd, 0x9d, 0x71, 0x09, 0xd5,
+ 0x39, 0xb6, 0xfc, 0x46, 0xe8, 0x50, 0xeb, 0xf9, 0xff, 0xd2, 0xac, 0xab,
+ 0x2a, 0xc7, 0x5f, 0xc9, 0x0b, 0x9f, 0x19, 0x3a, 0xff, 0xfb, 0x3d, 0xdc,
+ 0x97, 0x1c, 0x7d, 0xd7, 0x91, 0xd7, 0x47, 0xe7, 0x5f, 0xe7, 0xde, 0x1a,
+ 0x8d, 0x63, 0x88, 0x90, 0x12, 0xdf, 0xa9, 0xb5, 0x89, 0xea, 0xa3, 0xaf,
+ 0x48, 0xc4, 0x5b, 0x50, 0xcd, 0xbf, 0x7b, 0xac, 0xbc, 0xe7, 0x59, 0x85,
+ 0x6d, 0x77, 0xf6, 0x05, 0x82, 0xf1, 0x91, 0xa2, 0x36, 0x1e, 0xfb, 0x96,
+ 0xf1, 0x14, 0x4e, 0x7d, 0x28, 0x4f, 0xea, 0x6d, 0xfb, 0x8d, 0x77, 0x69,
+ 0xa2, 0xaa, 0xbf, 0xf3, 0xc9, 0x8c, 0xe3, 0x5d, 0xda, 0x68, 0x9b, 0x6c,
+ 0xc6, 0x1f, 0xea, 0xcc, 0xef, 0xf3, 0x19, 0xc6, 0xbb, 0xb4, 0xd1, 0x5f,
+ 0xdf, 0xb8, 0xd7, 0x76, 0x9a, 0x2c, 0x6b, 0xb6, 0xa4, 0x75, 0x98, 0xc3,
+ 0xcc, 0x98, 0xce, 0xfd, 0xa6, 0xf6, 0x14, 0x3a, 0xff, 0x08, 0x25, 0x9a,
+ 0x7f, 0x1d, 0x77, 0x3c, 0x75, 0xff, 0x67, 0xbd, 0x9c, 0x0e, 0x09, 0xd7,
+ 0x94, 0x96, 0x1d, 0x66, 0x31, 0x13, 0x2e, 0x62, 0x22, 0xda, 0x36, 0xb2,
+ 0x30, 0x98, 0x17, 0x21, 0x83, 0x7e, 0xe3, 0x5d, 0xda, 0x68, 0xb5, 0x6f,
+ 0xfc, 0xf2, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x28, 0x2b, 0xf4, 0x33, 0xb7,
+ 0x9c, 0x3a, 0xcc, 0x62, 0x29, 0xd6, 0x67, 0xf5, 0x2a, 0xff, 0x40, 0xff,
+ 0x0a, 0xee, 0xb3, 0xae, 0xe4, 0x1d, 0x52, 0x3c, 0x9d, 0xa3, 0x4b, 0xe6,
+ 0xbb, 0xb4, 0xd1, 0x71, 0x5f, 0xc0, 0x7d, 0xc3, 0x9c, 0x3a, 0xb8, 0x7b,
+ 0x5a, 0x2d, 0xbd, 0xc8, 0x59, 0xd7, 0xcf, 0xb4, 0x93, 0x9d, 0x7e, 0xe8,
+ 0x14, 0xc1, 0x3a, 0xf6, 0xd2, 0x34, 0xea, 0x09, 0xe2, 0xed, 0x13, 0xdf,
+ 0xe5, 0xbc, 0xb4, 0x81, 0xc3, 0xaf, 0xf4, 0x2d, 0xf6, 0x47, 0x36, 0x8e,
+ 0xbf, 0xb3, 0x8f, 0xe0, 0x41, 0xd7, 0xff, 0xce, 0x30, 0x9b, 0x5a, 0x4d,
+ 0x67, 0x73, 0x6c, 0xea, 0x09, 0xfe, 0x6c, 0x2b, 0xbf, 0xf9, 0x04, 0x12,
+ 0xcd, 0x69, 0x03, 0x87, 0x54, 0xc7, 0xcb, 0xe2, 0x4b, 0x31, 0x0a, 0xad,
+ 0x71, 0xff, 0x84, 0x5d, 0x1b, 0x76, 0x9f, 0xc9, 0x7c, 0x63, 0xf6, 0x31,
+ 0x7b, 0xf2, 0xa9, 0x5a, 0x7e, 0xa4, 0x1d, 0x7f, 0xe4, 0xdd, 0x56, 0xd7,
+ 0x3e, 0x7c, 0xee, 0xd9, 0xd7, 0xdd, 0x8f, 0x34, 0xea, 0x56, 0xa7, 0xda,
+ 0x14, 0xcb, 0xff, 0xca, 0xb2, 0x8c, 0xab, 0xce, 0x15, 0x57, 0xcf, 0x9d,
+ 0xdb, 0x3a, 0xfd, 0xc6, 0xbb, 0xb4, 0xd1, 0x74, 0xdf, 0xa0, 0x5c, 0x30,
+ 0x75, 0xe8, 0xf6, 0xd1, 0xd7, 0xd8, 0x1c, 0x09, 0xd7, 0xfc, 0xfb, 0x23,
+ 0xda, 0x03, 0x55, 0x27, 0x59, 0x85, 0x59, 0x3f, 0xd8, 0x85, 0x04, 0x8a,
+ 0x31, 0x89, 0x0c, 0xfa, 0x48, 0xe3, 0xc2, 0x41, 0x7f, 0xfd, 0x83, 0xe4,
+ 0x5f, 0x61, 0x05, 0xf8, 0xa1, 0xd7, 0xf4, 0xf1, 0xe7, 0x50, 0x07, 0x51,
+ 0xd7, 0xff, 0x47, 0x3f, 0xf9, 0xae, 0xc2, 0xdc, 0x4e, 0xbf, 0xd1, 0xcf,
+ 0xbd, 0xee, 0x7e, 0x75, 0x48, 0xfe, 0xba, 0x8b, 0x7f, 0x49, 0xe4, 0xe2,
+ 0xd3, 0xaf, 0xff, 0x67, 0xa1, 0x9f, 0xb3, 0xeb, 0x17, 0x0a, 0xe7, 0x59,
+ 0x85, 0x65, 0x32, 0x0c, 0x84, 0x24, 0xc4, 0x42, 0x57, 0x5c, 0x4e, 0x71,
+ 0x71, 0xa7, 0x5f, 0x63, 0x2a, 0xca, 0xce, 0xbf, 0xe4, 0xe0, 0xc6, 0xeb,
+ 0x7f, 0x1d, 0x7f, 0xff, 0xc0, 0xe4, 0xb5, 0xd7, 0x4e, 0x73, 0x80, 0xdd,
+ 0x38, 0xfa, 0x3a, 0xff, 0xc2, 0xec, 0xfb, 0x3a, 0xf3, 0x39, 0xd7, 0xff,
+ 0xf7, 0x44, 0x0e, 0xaf, 0x92, 0xee, 0x29, 0x81, 0x98, 0x07, 0x5c, 0xdc,
+ 0x3a, 0xa0, 0xfc, 0xd4, 0x5e, 0xbc, 0xa6, 0xa4, 0x75, 0xff, 0xa5, 0x9c,
+ 0xe3, 0xca, 0x7c, 0x64, 0xeb, 0xff, 0xb0, 0x31, 0x28, 0xe4, 0x7d, 0x71,
+ 0x3a, 0xff, 0xdb, 0x32, 0x4b, 0x0a, 0x6c, 0x80, 0x9d, 0x4b, 0x44, 0x1b,
+ 0xa1, 0x5c, 0xec, 0x4e, 0xa8, 0xea, 0x66, 0x7e, 0x42, 0xc3, 0x44, 0x5e,
+ 0x1d, 0xfb, 0x0c, 0x2a, 0xea, 0xae, 0x41, 0x94, 0xe3, 0x7f, 0xef, 0x23,
+ 0x50, 0x2e, 0x2a, 0x41, 0xd7, 0xfd, 0x1b, 0xf5, 0xf5, 0xe8, 0x64, 0xea,
+ 0x83, 0xf5, 0xe1, 0xe5, 0xc0, 0xe9, 0xd7, 0xe1, 0xce, 0xbf, 0x8e, 0xbf,
+ 0xa4, 0xf9, 0xb2, 0x02, 0x75, 0x2a, 0x0f, 0x49, 0x57, 0x92, 0xdf, 0x20,
+ 0x25, 0x07, 0x5f, 0x9e, 0x69, 0x27, 0x8e, 0xbf, 0xf4, 0x07, 0x91, 0x24,
+ 0xdf, 0xd8, 0x75, 0x49, 0x10, 0x9f, 0x90, 0x78, 0x9e, 0xff, 0xff, 0xa0,
+ 0x3d, 0xcd, 0xfc, 0x2f, 0xdf, 0xdf, 0x5a, 0x7e, 0x34, 0xeb, 0xfd, 0x99,
+ 0x8a, 0x28, 0xf2, 0x3a, 0x94, 0x44, 0xc7, 0x99, 0xaf, 0xdb, 0x13, 0x98,
+ 0x13, 0xaf, 0xff, 0xb5, 0xd4, 0xd7, 0xbb, 0x81, 0x4d, 0x60, 0x9d, 0x7b,
+ 0xb0, 0x38, 0x7e, 0xa0, 0x28, 0xbf, 0xd0, 0xbc, 0x45, 0xc2, 0xb9, 0xd7,
+ 0xfa, 0x4b, 0xd2, 0x0e, 0xf2, 0x3a, 0x9a, 0x7c, 0xd3, 0x19, 0xde, 0x77,
+ 0x69, 0xa2, 0x4c, 0xbd, 0xb4, 0x9a, 0x3a, 0x9a, 0x78, 0xbb, 0x44, 0xf7,
+ 0xe6, 0xaa, 0xca, 0xa5, 0x65, 0x50, 0x75, 0xfe, 0xcd, 0xfd, 0xe7, 0x96,
+ 0x8e, 0xa8, 0x3e, 0xde, 0x1d, 0x5f, 0xe1, 0x7f, 0x69, 0xa0, 0x13, 0xaf,
+ 0xff, 0xee, 0x67, 0xe9, 0xfb, 0x38, 0x9b, 0x07, 0x3d, 0xd4, 0x3a, 0xb1,
+ 0x11, 0xa8, 0x63, 0x52, 0x54, 0xc1, 0x90, 0x97, 0xe3, 0x42, 0xe1, 0x25,
+ 0xd8, 0x57, 0x5f, 0xc1, 0xfd, 0x51, 0xaf, 0xf6, 0xce, 0xbd, 0xa4, 0x09,
+ 0xd7, 0xf0, 0xc6, 0xeb, 0x7f, 0x1d, 0x7f, 0xd0, 0xdf, 0x03, 0xbc, 0x86,
+ 0x4e, 0xbf, 0xcd, 0x4e, 0x6a, 0x68, 0x73, 0xaf, 0xfe, 0x06, 0xba, 0xf2,
+ 0xeb, 0xca, 0x04, 0xea, 0xdc, 0xfd, 0x38, 0x65, 0x77, 0x52, 0x64, 0xc5,
+ 0xf8, 0x36, 0xb2, 0xcf, 0x42, 0xb6, 0xfb, 0xc8, 0xb7, 0x3a, 0xff, 0x27,
+ 0x75, 0x1e, 0x80, 0x9d, 0x58, 0x7a, 0x3e, 0x20, 0xbf, 0xe8, 0xef, 0x92,
+ 0x75, 0xc3, 0x4e, 0xbf, 0xff, 0x3b, 0x79, 0x1d, 0x1c, 0xf6, 0x30, 0xcb,
+ 0x2c, 0x95, 0x52, 0x45, 0x86, 0x88, 0x7c, 0x71, 0x7f, 0x35, 0xa0, 0x68,
+ 0xc1, 0xd7, 0xff, 0xb3, 0x79, 0x0c, 0x4b, 0x91, 0xe7, 0xf1, 0xd7, 0xfe,
+ 0x7f, 0x47, 0x35, 0xd8, 0x1f, 0x1d, 0x7e, 0xc9, 0x23, 0xec, 0x3a, 0x84,
+ 0xf8, 0xf4, 0x79, 0x52, 0x46, 0x60, 0x21, 0x57, 0x7f, 0xf8, 0x62, 0x5c,
+ 0xe0, 0x37, 0x4e, 0x3e, 0x8e, 0xbf, 0xfe, 0xd6, 0x28, 0x39, 0xed, 0x64,
+ 0x85, 0xd9, 0x3a, 0xed, 0x89, 0xd4, 0x4b, 0xf9, 0x26, 0xfb, 0x6a, 0x3b,
+ 0xa3, 0xaa, 0x0f, 0x53, 0x0c, 0x2f, 0xef, 0x08, 0x27, 0xdd, 0x5c, 0xeb,
+ 0xff, 0xd1, 0x38, 0xe6, 0x4f, 0xe5, 0x20, 0x64, 0x75, 0xff, 0x9c, 0x67,
+ 0xeb, 0xad, 0x34, 0x87, 0x53, 0xa2, 0xdc, 0x4c, 0x99, 0x49, 0xbc, 0xcb,
+ 0x2c, 0x95, 0x7d, 0x3a, 0xd3, 0x45, 0x30, 0x5f, 0xdd, 0x01, 0x3a, 0xdc,
+ 0x73, 0xc7, 0x13, 0x2b, 0xff, 0xff, 0x80, 0xe2, 0xde, 0x66, 0xc8, 0x1f,
+ 0x2e, 0x30, 0x43, 0x9b, 0xf8, 0xeb, 0xfd, 0x28, 0xe4, 0xf1, 0xc9, 0xce,
+ 0xbf, 0xb5, 0xa4, 0xc1, 0xfc, 0xeb, 0xdc, 0xc5, 0x73, 0xaf, 0xfd, 0x0c,
+ 0xfd, 0x9f, 0x58, 0xb8, 0x57, 0x3a, 0xb8, 0x88, 0xe5, 0x96, 0x78, 0x7a,
+ 0xa1, 0x1e, 0x59, 0x0c, 0x2b, 0xf2, 0x7a, 0x7c, 0x64, 0xeb, 0xfe, 0x86,
+ 0xf4, 0x41, 0xe8, 0xd1, 0xd7, 0xff, 0x26, 0xd4, 0x36, 0x17, 0x81, 0x75,
+ 0x9d, 0x7f, 0xfe, 0xf7, 0x72, 0x5f, 0x1b, 0xd4, 0xf6, 0xed, 0x4e, 0x1d,
+ 0x5c, 0x47, 0xda, 0xca, 0x3a, 0x6e, 0x28, 0x97, 0xfc, 0xb8, 0xe6, 0xcc,
+ 0xe4, 0x4c, 0x75, 0xff, 0xb8, 0xd5, 0xc6, 0xfa, 0xcd, 0x98, 0x75, 0xfe,
+ 0x1f, 0xf6, 0xf0, 0x38, 0xb3, 0xaf, 0xe1, 0xf9, 0xb7, 0x9c, 0x83, 0xaa,
+ 0x11, 0x4b, 0x88, 0x0e, 0x6b, 0x7f, 0xd8, 0xff, 0xfc, 0xc0, 0xbc, 0x8e,
+ 0xbf, 0xfc, 0xf3, 0xf5, 0x20, 0x72, 0x64, 0xe2, 0x1d, 0x58, 0x9e, 0x47,
+ 0xe7, 0x9a, 0x86, 0xff, 0x8b, 0x59, 0x39, 0xbf, 0x0e, 0x75, 0xfc, 0x75,
+ 0xff, 0xa5, 0x03, 0x3f, 0xde, 0x08, 0x24, 0x75, 0x2b, 0x9f, 0x2c, 0xc4,
+ 0xb7, 0xde, 0x9f, 0x02, 0x75, 0xff, 0x22, 0x9f, 0x79, 0xfa, 0xd3, 0x47,
+ 0x54, 0xc7, 0xbd, 0xb6, 0x45, 0x79, 0x96, 0x59, 0x3a, 0xff, 0xfd, 0x8b,
+ 0xf0, 0xc7, 0xf8, 0x1d, 0x62, 0xe1, 0xa5, 0x30, 0x5f, 0xdf, 0xec, 0x6f,
+ 0x52, 0x05, 0xa7, 0x5f, 0xee, 0x47, 0x91, 0xa8, 0x13, 0xaf, 0xd2, 0x9b,
+ 0x31, 0xa7, 0x5b, 0x87, 0x52, 0xb0, 0x7d, 0x10, 0x63, 0xf4, 0x9e, 0xb1,
+ 0x3f, 0x94, 0x84, 0x27, 0x51, 0x45, 0x8f, 0x50, 0x98, 0xbd, 0xe9, 0x74,
+ 0xeb, 0x21, 0xd7, 0xf7, 0x63, 0xe3, 0x52, 0x73, 0xaf, 0xee, 0x3f, 0x06,
+ 0x24, 0x75, 0xff, 0xf4, 0x29, 0xae, 0xba, 0x7a, 0x16, 0x2e, 0xa1, 0xd7,
+ 0xfe, 0xcd, 0x9d, 0x4f, 0x9a, 0xd2, 0x2c, 0xeb, 0x9f, 0xd2, 0x44, 0x7f,
+ 0x53, 0xaf, 0xfc, 0x92, 0x4e, 0x6f, 0x03, 0x1a, 0x3a, 0x95, 0xa2, 0x6c,
+ 0x41, 0x0f, 0xe1, 0x78, 0xc2, 0xeb, 0xc5, 0xd7, 0x49, 0x85, 0x6d, 0xb4,
+ 0xbe, 0x55, 0x34, 0x44, 0x2c, 0x25, 0x0c, 0x9c, 0x95, 0xf2, 0xa2, 0xd3,
+ 0x63, 0x4e, 0xde, 0x35, 0x04, 0x30, 0x9a, 0x1f, 0x1c, 0x8c, 0x4f, 0xb0,
+ 0xd7, 0x78, 0x4a, 0xfe, 0x4c, 0x31, 0xb1, 0x6a, 0x57, 0x4f, 0xa5, 0x57,
+ 0xed, 0xa9, 0x7d, 0x8d, 0xfa, 0xff, 0xf7, 0x31, 0x90, 0xf7, 0x26, 0x1c,
+ 0xe4, 0x8e, 0xbd, 0xcc, 0x57, 0x3a, 0xff, 0xd0, 0xcf, 0xd9, 0xf5, 0x8b,
+ 0x85, 0x73, 0xab, 0x88, 0xac, 0x5a, 0x57, 0x87, 0xaf, 0xff, 0x9d, 0x71,
+ 0xc6, 0xf0, 0x0a, 0x70, 0x0f, 0xa3, 0xab, 0x11, 0x00, 0x03, 0x0b, 0xfd,
+ 0xc6, 0x81, 0xc2, 0xb8, 0x3a, 0xff, 0xe8, 0xe7, 0xdf, 0x27, 0xbb, 0x81,
+ 0x43, 0xaf, 0xfd, 0xd1, 0x89, 0xfe, 0xf7, 0xae, 0xae, 0x75, 0x42, 0x2e,
+ 0x67, 0x32, 0xc4, 0x4b, 0xcf, 0xc9, 0xce, 0xb9, 0x96, 0x4e, 0xbc, 0xed,
+ 0x61, 0xa6, 0xd1, 0x91, 0xcb, 0xfa, 0x38, 0xf2, 0x4e, 0x9d, 0x7e, 0xc5,
+ 0xf5, 0xc2, 0x75, 0x98, 0x86, 0xfb, 0xdb, 0x23, 0xe8, 0x50, 0xa9, 0xb2,
+ 0xc2, 0xf9, 0x0a, 0x07, 0xad, 0x37, 0xc6, 0x54, 0xbe, 0xa1, 0xb7, 0xb1,
+ 0x8d, 0x93, 0x4d, 0xa2, 0xba, 0x93, 0xaf, 0xf3, 0x0c, 0xf1, 0x06, 0xf1,
+ 0x94, 0xf0, 0xa1, 0x70, 0x8b, 0xec, 0x65, 0x7f, 0xc3, 0x5b, 0x52, 0xcd,
+ 0xbd, 0x29, 0xf4, 0x15, 0xfb, 0xa5, 0xfd, 0xa8, 0x9a, 0x49, 0x31, 0xd7,
+ 0xff, 0xa2, 0x7c, 0xf4, 0x0a, 0x7f, 0x9b, 0xf8, 0xeb, 0x31, 0xa3, 0xf7,
+ 0xfa, 0x5d, 0x7e, 0xe3, 0x5d, 0xda, 0x68, 0x8d, 0x6f, 0x29, 0xbe, 0x8e,
+ 0xb3, 0x18, 0x7a, 0x3e, 0x33, 0xbf, 0x71, 0xae, 0xed, 0x34, 0x54, 0xb7,
+ 0x3b, 0x4d, 0x10, 0xd5, 0x98, 0xc3, 0xd5, 0x73, 0x3b, 0xf7, 0x1a, 0xee,
+ 0xd3, 0x44, 0x7d, 0x7f, 0xfc, 0x2f, 0xe9, 0x42, 0x9f, 0x23, 0xda, 0x8f,
+ 0xce, 0xbc, 0xf2, 0x63, 0x11, 0x09, 0xf4, 0xce, 0xff, 0xcf, 0x3c, 0x75,
+ 0x38, 0x90, 0xb3, 0xaf, 0xf4, 0x73, 0x07, 0xd9, 0xd3, 0xaf, 0x2f, 0x18,
+ 0xdb, 0x3e, 0xcf, 0xa7, 0x94, 0xc2, 0x36, 0xe2, 0x14, 0x57, 0xff, 0xfd,
+ 0x20, 0x71, 0x47, 0xd6, 0x06, 0x37, 0xd7, 0xdf, 0x28, 0x8a, 0x1d, 0x7f,
+ 0x03, 0x7d, 0xe5, 0x9e, 0x3a, 0xff, 0xf2, 0xac, 0xa3, 0x2a, 0xf3, 0x85,
+ 0x55, 0xf3, 0xe7, 0x76, 0xce, 0xbf, 0x71, 0xae, 0xed, 0x34, 0x58, 0xf7,
+ 0x3e, 0x8e, 0xbf, 0xa7, 0xfb, 0xce, 0x67, 0x0e, 0xa9, 0x1e, 0x2b, 0x8a,
+ 0xdf, 0xf0, 0xba, 0x9d, 0x48, 0x19, 0xce, 0xbf, 0xff, 0x7f, 0x29, 0xd5,
+ 0x68, 0x56, 0xe7, 0x6f, 0x3e, 0x7c, 0xee, 0xd9, 0xd7, 0xe4, 0xf7, 0x93,
+ 0xc7, 0x5f, 0x73, 0x99, 0xb6, 0x75, 0x61, 0xe5, 0x39, 0x35, 0xfb, 0x39,
+ 0x99, 0x31, 0xd6, 0x62, 0x15, 0x64, 0x4e, 0xd9, 0x22, 0xfc, 0x62, 0x47,
+ 0x89, 0x88, 0x7a, 0x6f, 0xa8, 0x5a, 0xfd, 0x20, 0xbc, 0xab, 0x2d, 0x43,
+ 0xaf, 0xe5, 0x40, 0xe7, 0x5f, 0xc7, 0x5f, 0xe7, 0xff, 0x4f, 0xef, 0x39,
+ 0xd7, 0x2d, 0xa7, 0x50, 0x9e, 0x47, 0x8c, 0xaf, 0xfd, 0x8c, 0xf3, 0x05,
+ 0xf7, 0x96, 0x8e, 0xbf, 0x66, 0xba, 0x8c, 0x9d, 0x7d, 0xfa, 0xd3, 0x87,
+ 0x5f, 0xff, 0xf4, 0x70, 0x70, 0x39, 0xde, 0xa3, 0x7a, 0x9e, 0xd3, 0xee,
+ 0x75, 0x22, 0x21, 0xba, 0x45, 0x7f, 0x47, 0x3f, 0xdb, 0x07, 0x8e, 0xbf,
+ 0xe8, 0x1f, 0x2a, 0x9f, 0xc0, 0x83, 0xaf, 0xff, 0x47, 0x61, 0x6d, 0xea,
+ 0x7b, 0x31, 0x67, 0x5f, 0x7f, 0xfa, 0x7d, 0x3a, 0xf3, 0xbb, 0x4d, 0x16,
+ 0x85, 0xff, 0x9d, 0x9d, 0xa6, 0xbf, 0x27, 0xc6, 0x4e, 0xbf, 0xbf, 0x81,
+ 0x8f, 0x68, 0xea, 0x6a, 0x25, 0xb8, 0x4f, 0xfa, 0x1d, 0xff, 0xff, 0xf2,
+ 0x73, 0xae, 0x29, 0x1e, 0x4e, 0xc6, 0xbb, 0x9a, 0xe6, 0x37, 0x3c, 0x75,
+ 0x49, 0x50, 0xb0, 0x4c, 0x5a, 0x74, 0x88, 0xfc, 0x85, 0xdf, 0x4c, 0x6e,
+ 0xc5, 0x9d, 0x7f, 0xf3, 0xef, 0xb3, 0xaa, 0xe9, 0xe1, 0x85, 0x9d, 0x5c,
+ 0x3d, 0xd7, 0x15, 0xbf, 0xff, 0x27, 0xb4, 0xfb, 0xeb, 0x59, 0xd4, 0xd0,
+ 0x27, 0x3a, 0xff, 0xf8, 0x13, 0xf1, 0x3d, 0x38, 0x39, 0x2d, 0x2b, 0xa1,
+ 0xd5, 0xd4, 0x55, 0x8a, 0xb5, 0xff, 0xf0, 0x39, 0xc8, 0x1c, 0x51, 0x3b,
+ 0xdc, 0xfa, 0x75, 0x95, 0x27, 0x57, 0x0f, 0x90, 0x0a, 0x17, 0xf9, 0x60,
+ 0x1f, 0x68, 0x1c, 0x3a, 0xb8, 0x7a, 0xbb, 0x64, 0x57, 0xf6, 0xc9, 0xbb,
+ 0x9f, 0xb9, 0xd7, 0xe1, 0x6b, 0xe9, 0x0e, 0xbf, 0xff, 0xb8, 0x31, 0x1b,
+ 0xfc, 0xd7, 0x86, 0x03, 0xd8, 0xf1, 0xd7, 0x27, 0x4e, 0xbe, 0x90, 0xbf,
+ 0xd3, 0xaf, 0xf0, 0x5f, 0xfe, 0x71, 0xff, 0x3a, 0xfd, 0x9c, 0x6a, 0xbb,
+ 0x27, 0x52, 0x1e, 0xf8, 0x9a, 0x54, 0x26, 0x6d, 0x84, 0xaa, 0xeb, 0x6e,
+ 0x2a, 0x08, 0x40, 0xde, 0x75, 0x74, 0x3a, 0xff, 0xdf, 0x7c, 0xa2, 0x29,
+ 0x18, 0x30, 0x75, 0xfb, 0xef, 0x86, 0x3f, 0x3a, 0xb7, 0x44, 0x2f, 0x07,
+ 0x76, 0x1f, 0xdf, 0xa3, 0xd9, 0xd8, 0x3a, 0xff, 0xff, 0xf7, 0x50, 0x38,
+ 0x93, 0xf6, 0x23, 0xe6, 0x6f, 0x2d, 0x27, 0x9c, 0x70, 0xeb, 0xff, 0x66,
+ 0xf2, 0xd4, 0xdc, 0x7f, 0x68, 0xeb, 0xff, 0xec, 0xf6, 0xb2, 0x6e, 0xc6,
+ 0xcc, 0xef, 0x60, 0xeb, 0xfe, 0x18, 0x89, 0xb3, 0x62, 0x70, 0xea, 0x9d,
+ 0x36, 0x36, 0x92, 0xfe, 0xec, 0x28, 0x1e, 0x50, 0xbf, 0x7c, 0x9a, 0x49,
+ 0x31, 0xd5, 0x0a, 0x83, 0x72, 0x39, 0x64, 0x4c, 0xbf, 0xfb, 0xa9, 0xf3,
+ 0x07, 0x13, 0x8f, 0xb0, 0xeb, 0xff, 0xfd, 0xd8, 0x1c, 0xff, 0x58, 0x1e,
+ 0xc4, 0xeb, 0x00, 0x84, 0xea, 0x51, 0x14, 0x9e, 0x44, 0xbf, 0xff, 0xa2,
+ 0x6c, 0x0f, 0x63, 0x67, 0x73, 0xc3, 0x10, 0xb3, 0xaf, 0xed, 0xf5, 0xf6,
+ 0x70, 0x09, 0xd7, 0xfd, 0x0d, 0xea, 0x4c, 0xef, 0x39, 0xd4, 0xb4, 0x61,
+ 0xba, 0xd7, 0xe6, 0x37, 0xfa, 0x51, 0xc9, 0xe3, 0x93, 0x9d, 0x7f, 0xc8,
+ 0x01, 0x97, 0x23, 0x02, 0x75, 0xff, 0xff, 0x77, 0x24, 0xde, 0xa7, 0x63,
+ 0x39, 0x2f, 0x0c, 0x2f, 0x47, 0x56, 0x91, 0x35, 0xe3, 0x6a, 0x84, 0x78,
+ 0xe4, 0x33, 0xaf, 0xf7, 0x1b, 0x36, 0x27, 0x40, 0x75, 0xfe, 0x5c, 0x34,
+ 0x5f, 0x7f, 0x1d, 0x7f, 0x72, 0x3d, 0x3e, 0x32, 0x75, 0xff, 0xff, 0xf2,
+ 0x03, 0x9d, 0xc9, 0xa6, 0x7e, 0x4d, 0xee, 0x83, 0xfd, 0x62, 0x6c, 0x0c,
+ 0x1d, 0x7e, 0xf7, 0x5c, 0x54, 0x3a, 0xff, 0x84, 0x13, 0x87, 0xb8, 0x30,
+ 0x75, 0xb0, 0x28, 0xe0, 0xc8, 0x41, 0x34, 0x9e, 0xff, 0xf7, 0x3f, 0x6f,
+ 0xe3, 0x9e, 0xd3, 0xb8, 0x9d, 0x50, 0x9f, 0xae, 0x19, 0xa1, 0x90, 0xc6,
+ 0x1c, 0x03, 0x9b, 0xfd, 0x9d, 0x99, 0x3a, 0x8b, 0x3a, 0xff, 0x4b, 0x39,
+ 0xa1, 0x89, 0xce, 0xbd, 0xb7, 0x93, 0x9d, 0x7b, 0x3a, 0xe7, 0x5f, 0xa6,
+ 0x08, 0x00, 0x27, 0x50, 0x4f, 0x09, 0xc6, 0xaf, 0xf6, 0x33, 0x8d, 0x6e,
+ 0x32, 0x75, 0xff, 0x6e, 0xbc, 0xc1, 0xf6, 0xde, 0x1d, 0x79, 0x49, 0x00,
+ 0xeb, 0xf7, 0x63, 0x93, 0xac, 0xeb, 0xfc, 0x07, 0x1e, 0xe3, 0xcc, 0x75,
+ 0xb7, 0x98, 0xf6, 0x59, 0x28, 0xa4, 0x45, 0x0b, 0xbb, 0x56, 0x26, 0x5e,
+ 0xe6, 0x63, 0x0d, 0xba, 0xc5, 0x49, 0x1b, 0x99, 0x21, 0x93, 0xb0, 0xea,
+ 0x35, 0x0b, 0xbd, 0x07, 0x5c, 0xfe, 0x3a, 0xb8, 0x6a, 0xba, 0x2b, 0x7f,
+ 0xdc, 0xce, 0xe4, 0xff, 0x13, 0x47, 0x56, 0x1e, 0xd8, 0x08, 0x6f, 0xe4,
+ 0x10, 0x4b, 0x34, 0x75, 0xff, 0xb3, 0xd1, 0xbf, 0xef, 0xde, 0xa1, 0xd6,
+ 0x59, 0xd7, 0xf2, 0x08, 0x25, 0x9a, 0xf8, 0x79, 0xdb, 0x0f, 0xa9, 0x44,
+ 0x60, 0x79, 0xe6, 0xcc, 0x2b, 0x6d, 0xa0, 0xb2, 0xa8, 0x8a, 0x1d, 0xe7,
+ 0x21, 0x91, 0xf0, 0x61, 0x5b, 0x92, 0x8e, 0x14, 0x85, 0xd3, 0x61, 0x98,
+ 0x90, 0xdb, 0x98, 0x95, 0x71, 0xb3, 0x76, 0x57, 0x13, 0xc3, 0x67, 0xf8,
+ 0x73, 0x8c, 0x64, 0x3a, 0x94, 0x37, 0xe9, 0x52, 0xbb, 0x70, 0xd5, 0xfb,
+ 0x0e, 0x1b, 0xfb, 0x69, 0x02, 0x31, 0x31, 0xd7, 0xa1, 0xc4, 0xeb, 0xec,
+ 0xeb, 0xf8, 0xeb, 0x2a, 0x30, 0xfa, 0x3a, 0x5e, 0x23, 0x37, 0xff, 0xff,
+ 0xba, 0xe3, 0xed, 0x42, 0x4b, 0x36, 0x87, 0xd1, 0xd8, 0x50, 0x11, 0xb4,
+ 0x75, 0xf6, 0x6b, 0xf4, 0x3a, 0xfd, 0xc6, 0xbb, 0xb4, 0xd1, 0x6b, 0x5f,
+ 0xe5, 0xa2, 0xde, 0x6c, 0xe9, 0xd7, 0xf6, 0x6d, 0x69, 0xc5, 0xa7, 0x5e,
+ 0xe4, 0x2c, 0xeb, 0xfb, 0xb9, 0xa8, 0x9f, 0x68, 0xeb, 0xfe, 0x93, 0x19,
+ 0xc6, 0xbb, 0xb4, 0xd1, 0x41, 0xd6, 0x1f, 0xab, 0x98, 0x5f, 0x64, 0xd1,
+ 0xe3, 0xaf, 0xfa, 0x25, 0x1c, 0x9e, 0x39, 0x39, 0xd7, 0xff, 0xef, 0x69,
+ 0x27, 0x7d, 0x38, 0xbf, 0xbb, 0x13, 0x1d, 0x66, 0x15, 0x4a, 0xb0, 0xe0,
+ 0xde, 0x4f, 0x58, 0x42, 0x86, 0x73, 0x19, 0x70, 0xb9, 0x70, 0x90, 0xe9,
+ 0x00, 0x90, 0xfd, 0x39, 0xbf, 0xfc, 0xc2, 0xde, 0x4c, 0x67, 0x1a, 0xee,
+ 0xd3, 0x45, 0x17, 0x7f, 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x8b, 0xaa, 0xa1,
+ 0xbf, 0xf2, 0x93, 0xe3, 0x5f, 0x52, 0x38, 0x65, 0xca, 0xf0, 0xed, 0x69,
+ 0x47, 0xfc, 0xe5, 0x0e, 0xa1, 0x53, 0xe5, 0x7b, 0xf7, 0x1a, 0xee, 0xd3,
+ 0x44, 0x43, 0x7b, 0xb8, 0x13, 0xaf, 0xb3, 0x62, 0x70, 0xeb, 0x31, 0x87,
+ 0xe1, 0xb9, 0x9a, 0xb8, 0xdd, 0xb6, 0xce, 0xbe, 0x8e, 0xc2, 0xce, 0xbe,
+ 0x6b, 0xbb, 0x4d, 0x11, 0xb5, 0x34, 0xf3, 0x78, 0x41, 0x66, 0x02, 0x88,
+ 0x2c, 0x60, 0xbf, 0xcc, 0x67, 0x1a, 0xee, 0xd3, 0x45, 0x37, 0x7e, 0xe3,
+ 0x5d, 0xda, 0x68, 0xa8, 0x2f, 0x66, 0xec, 0x9d, 0x66, 0x30, 0xf4, 0x3a,
+ 0x67, 0x7f, 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x8a, 0x9a, 0xfd, 0xc6, 0xbb,
+ 0xb4, 0xd1, 0x58, 0x5f, 0x91, 0x90, 0x83, 0x87, 0x5c, 0xbd, 0x1d, 0x7f,
+ 0x26, 0xdb, 0xc2, 0x6d, 0x9d, 0x7f, 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x88,
+ 0xfe, 0xa0, 0xfb, 0xe4, 0x61, 0x7b, 0x22, 0x73, 0xaf, 0xf6, 0x6f, 0x27,
+ 0x92, 0x09, 0xd7, 0x3f, 0x8e, 0xb3, 0x18, 0x9b, 0x13, 0x4c, 0xd6, 0x50,
+ 0xf0, 0x85, 0x12, 0x1f, 0x0d, 0xed, 0x98, 0xdf, 0xfe, 0x61, 0x6f, 0x26,
+ 0x33, 0x8d, 0x77, 0x69, 0xa2, 0x6f, 0xbf, 0xf9, 0x6f, 0x26, 0x33, 0x8d,
+ 0x77, 0x69, 0xa2, 0x7e, 0xbf, 0x9f, 0xb9, 0xe8, 0x09, 0xd7, 0x0b, 0x4e,
+ 0xbe, 0xd4, 0xcb, 0xd1, 0xd7, 0xf9, 0xbd, 0x4f, 0x66, 0x2c, 0xeb, 0xb6,
+ 0x34, 0xf1, 0x81, 0x54, 0x22, 0x39, 0x05, 0x74, 0x47, 0xe3, 0x1b, 0xfc,
+ 0xab, 0x95, 0x81, 0xc9, 0xe3, 0x73, 0xaf, 0xca, 0xca, 0xa3, 0x6f, 0x37,
+ 0x3a, 0xfe, 0x56, 0x1e, 0x7e, 0xa2, 0xb9, 0xd7, 0xe5, 0x6d, 0x45, 0x31,
+ 0x5c, 0xeb, 0xb6, 0x34, 0xf1, 0x80, 0xdb, 0xa7, 0x52, 0xb2, 0x98, 0x6a,
+ 0xb0, 0x7c, 0xa8, 0x34, 0x55, 0xc6, 0xbe, 0x31, 0x01, 0x2d, 0xf2, 0xb7,
+ 0xc7, 0xc3, 0xaf, 0x95, 0x53, 0xaf, 0x47, 0x5f, 0xff, 0xca, 0xd8, 0xbf,
+ 0xa0, 0x5a, 0x8b, 0x08, 0x1f, 0x92, 0x3a, 0xff, 0x9f, 0xa9, 0xb1, 0x86,
+ 0x59, 0x64, 0xab, 0xfd, 0xd7, 0xf7, 0x9d, 0xd9, 0x3a, 0x95, 0x48, 0xf4,
+ 0x55, 0xe4, 0xea, 0xd5, 0x75, 0x57, 0x1f, 0x5f, 0xff, 0xe5, 0x65, 0x51,
+ 0xae, 0x42, 0x7b, 0xb8, 0x14, 0xd6, 0x0f, 0xe7, 0x5f, 0xca, 0xf1, 0xc7,
+ 0x79, 0x1d, 0x7e, 0xea, 0x3f, 0xea, 0xb8, 0xea, 0x56, 0x11, 0x86, 0xab,
+ 0x34, 0x78, 0xba, 0xce, 0x75, 0xf9, 0x54, 0xad, 0x3f, 0x52, 0x0e, 0xbf,
+ 0xfe, 0x88, 0x88, 0x88, 0x88, 0x88, 0xdf, 0x47, 0x5e, 0x4d, 0xf0, 0xeb,
+ 0xf7, 0x12, 0x77, 0x59, 0x57, 0x32, 0xc9, 0x55, 0x86, 0xfd, 0x92, 0x7b,
+ 0x00, 0xa6, 0x0d, 0x0d, 0x42, 0x39, 0x7f, 0x49, 0xd3, 0xdd, 0xf9, 0xdc,
+ 0x63, 0x68, 0xeb, 0xff, 0xc8, 0x38, 0xb8, 0xd6, 0xb2, 0x5b, 0x78, 0x75,
+ 0xff, 0xee, 0xc4, 0x9f, 0x02, 0x9b, 0x35, 0xfb, 0x4e, 0xbf, 0xdc, 0x00,
+ 0x83, 0xc0, 0xf1, 0xd7, 0xbb, 0x02, 0x75, 0xa1, 0x0f, 0x37, 0xc6, 0x75,
+ 0x08, 0xbe, 0xec, 0x26, 0x2f, 0x0a, 0x41, 0xd7, 0xe8, 0xfa, 0xbe, 0xa1,
+ 0xd5, 0xc3, 0xc1, 0x11, 0x9b, 0xfa, 0x5a, 0xf6, 0x0a, 0x87, 0x5e, 0x65,
+ 0xd9, 0x3a, 0xff, 0xf7, 0xb8, 0xf3, 0x87, 0xb1, 0xaf, 0x03, 0xa7, 0x5d,
+ 0x8b, 0xe9, 0xf4, 0x68, 0x76, 0xfc, 0xed, 0xea, 0x70, 0xeb, 0xff, 0xff,
+ 0xc2, 0xea, 0x27, 0x22, 0x5f, 0x3a, 0x8b, 0x0c, 0x7c, 0xdb, 0x07, 0x53,
+ 0x87, 0x5f, 0x3c, 0x93, 0x73, 0xaf, 0xfd, 0xd4, 0xf6, 0x73, 0x80, 0x9f,
+ 0x61, 0xd7, 0xfc, 0x9e, 0xce, 0x70, 0x13, 0xec, 0x3a, 0xf6, 0x80, 0x3f,
+ 0x0f, 0xf3, 0xa8, 0x34, 0x14, 0xe8, 0xb8, 0x5b, 0xd2, 0x61, 0x7d, 0xd4,
+ 0x27, 0x6d, 0x07, 0x5f, 0xff, 0x46, 0xf2, 0x71, 0xff, 0xe7, 0xe9, 0xc4,
+ 0x50, 0xea, 0xdb, 0x3e, 0x2d, 0xa0, 0xfb, 0xe9, 0xd6, 0x92, 0x3a, 0xfa,
+ 0x3f, 0xfa, 0xb3, 0xaf, 0x84, 0x0f, 0x23, 0xa9, 0xa7, 0x89, 0xa2, 0x4b,
+ 0xfd, 0xd8, 0x5b, 0x1f, 0xff, 0x07, 0x54, 0x22, 0xf7, 0x19, 0x90, 0x8a,
+ 0xfe, 0x99, 0x3b, 0xec, 0x69, 0xd5, 0xc3, 0xda, 0x72, 0xdb, 0xfe, 0xdc,
+ 0x3f, 0x61, 0x5f, 0xa0, 0xd1, 0xd7, 0xff, 0xe0, 0xf6, 0x38, 0x9f, 0xc7,
+ 0xd8, 0x98, 0x61, 0x67, 0x5f, 0xe5, 0x20, 0x7d, 0xa7, 0xe9, 0xd4, 0x88,
+ 0x88, 0x75, 0x6a, 0x84, 0x74, 0x0c, 0x31, 0xef, 0xf7, 0x62, 0x7e, 0x46,
+ 0x04, 0xeb, 0xff, 0xe1, 0xcd, 0x8d, 0x7e, 0x4e, 0xfe, 0x7d, 0xff, 0x3a,
+ 0xa1, 0x10, 0x8e, 0x65, 0x7f, 0x85, 0xe7, 0xde, 0x51, 0xb4, 0x75, 0xfe,
+ 0xd7, 0x5f, 0xef, 0x62, 0x47, 0x54, 0xe7, 0xd5, 0xb9, 0xb5, 0xec, 0xc9,
+ 0x8e, 0xbf, 0xe8, 0x90, 0xbf, 0xa4, 0x9b, 0x0e, 0xbd, 0xf6, 0x3f, 0x3a,
+ 0xba, 0x7a, 0xda, 0x38, 0xb2, 0xb9, 0xd7, 0xbd, 0x2c, 0x3a, 0xed, 0x61,
+ 0xd7, 0xff, 0x6a, 0x38, 0xdf, 0x0e, 0x4e, 0xe2, 0x75, 0x62, 0x29, 0xd0,
+ 0x89, 0xc4, 0xff, 0x1b, 0xf0, 0xad, 0xfc, 0x09, 0x81, 0xe8, 0xe9, 0xd7,
+ 0xff, 0x06, 0x3c, 0xfa, 0xce, 0xf5, 0x16, 0x75, 0xfe, 0x9c, 0x30, 0xfc,
+ 0xfc, 0x07, 0x5e, 0xf2, 0x4c, 0x75, 0x42, 0x24, 0xb1, 0x0b, 0x46, 0x97,
+ 0xe8, 0x57, 0x46, 0x5a, 0x75, 0x43, 0x2b, 0xa2, 0x73, 0x09, 0x13, 0x86,
+ 0x30, 0x7c, 0x68, 0xdc, 0x85, 0x25, 0x1b, 0xcd, 0x0b, 0x1e, 0x46, 0x7e,
+ 0xb8, 0xc2, 0x7b, 0x0a, 0xa7, 0x84, 0x5f, 0xe4, 0x83, 0x18, 0xc6, 0x92,
+ 0x3d, 0x0c, 0x0f, 0xa5, 0xd7, 0xff, 0xfc, 0xab, 0xd5, 0x51, 0x8a, 0xd7,
+ 0x8a, 0xa5, 0x5b, 0x62, 0xba, 0xae, 0x07, 0xcf, 0x9d, 0xdb, 0x3a, 0xf4,
+ 0xdf, 0x56, 0x75, 0xff, 0x67, 0xb5, 0x9e, 0xee, 0x7e, 0x75, 0x39, 0xeb,
+ 0x88, 0xfd, 0xce, 0x27, 0x57, 0x0d, 0xa2, 0xc8, 0x2f, 0xa3, 0xd8, 0xb3,
+ 0xaf, 0xde, 0x81, 0x4f, 0xce, 0xbf, 0xb1, 0x97, 0xfd, 0x78, 0x75, 0x7c,
+ 0x3f, 0x3c, 0x20, 0x12, 0x6b, 0xf7, 0x27, 0x8f, 0x68, 0xeb, 0xe7, 0xe3,
+ 0xc8, 0xeb, 0x73, 0x0f, 0x20, 0x4a, 0x2f, 0x32, 0xcb, 0x27, 0x5f, 0x4e,
+ 0x29, 0x05, 0x30, 0x5f, 0xdf, 0xf2, 0xbf, 0x5c, 0x64, 0x18, 0x9c, 0xeb,
+ 0xb7, 0x91, 0xd7, 0xf9, 0x48, 0xf6, 0xba, 0xe0, 0x3a, 0xfc, 0x93, 0xe6,
+ 0xfe, 0x3a, 0xe4, 0x69, 0xd5, 0x08, 0x87, 0x50, 0x5d, 0x66, 0x7e, 0x28,
+ 0xbf, 0x28, 0xfa, 0xd9, 0x23, 0xab, 0x73, 0xe7, 0xf1, 0xed, 0x2a, 0xca,
+ 0xfa, 0xa2, 0x31, 0xe0, 0xc2, 0x51, 0x1d, 0xfa, 0x8a, 0xe6, 0x00, 0x8c,
+ 0xa6, 0xff, 0xed, 0x8c, 0xe6, 0x85, 0x23, 0x99, 0x39, 0xd7, 0xff, 0xff,
+ 0xfe, 0x57, 0xf9, 0xdc, 0xde, 0x5d, 0x5f, 0xc6, 0xf4, 0x1e, 0xf6, 0x0f,
+ 0x73, 0xd0, 0x1f, 0x9f, 0x3b, 0xb6, 0x75, 0xff, 0x07, 0x00, 0xa9, 0x4e,
+ 0xba, 0xce, 0xbf, 0x42, 0xc7, 0x26, 0x3b, 0x0d, 0xdd, 0xed, 0x98, 0x13,
+ 0xaf, 0xf2, 0x9d, 0x48, 0x10, 0x41, 0xd5, 0xd3, 0xce, 0x71, 0xda, 0x0a,
+ 0x29, 0x35, 0x08, 0x3b, 0xfa, 0x25, 0xd8, 0xd8, 0x87, 0x5f, 0x9f, 0x80,
+ 0x7d, 0x1d, 0x74, 0xbc, 0x75, 0xf4, 0xd1, 0xe7, 0x3a, 0xf8, 0x1f, 0xe0,
+ 0xb4, 0xdb, 0x80, 0x5a, 0xd2, 0x3a, 0xa7, 0x3c, 0x8e, 0x9c, 0x5f, 0xfd,
+ 0x1d, 0xfa, 0x1f, 0x26, 0x4d, 0x0b, 0x3a, 0xfa, 0x3c, 0x05, 0x9d, 0x46,
+ 0x88, 0x3a, 0xfe, 0x79, 0xff, 0x71, 0x09, 0x2b, 0x06, 0xdb, 0x4d, 0x3d,
+ 0x2d, 0xb1, 0x7a, 0x5a, 0x27, 0xbc, 0xe7, 0x7f, 0xfe, 0x5e, 0x9e, 0x5d,
+ 0x4c, 0xf6, 0xb9, 0x81, 0xc3, 0xaf, 0xfa, 0x3c, 0x39, 0xb0, 0x73, 0x47,
+ 0x54, 0x22, 0xb7, 0x08, 0xf4, 0xa7, 0x7f, 0x3f, 0x61, 0x5c, 0x12, 0x3a,
+ 0xa4, 0xab, 0x89, 0xa5, 0xbc, 0x85, 0x2a, 0xc8, 0xfd, 0x1c, 0x86, 0xc2,
+ 0xeb, 0xfa, 0x43, 0x9b, 0xfb, 0x0e, 0xbf, 0xff, 0x7d, 0xff, 0xf8, 0xdf,
+ 0x27, 0x0b, 0xbb, 0x5c, 0x27, 0x54, 0x22, 0x17, 0x85, 0x97, 0xf9, 0xc7,
+ 0xd2, 0xce, 0x61, 0xd7, 0xf0, 0xa7, 0xfa, 0xea, 0x1d, 0x77, 0x02, 0x75,
+ 0xcc, 0xb2, 0x75, 0x48, 0xd7, 0x32, 0x2d, 0x7a, 0x13, 0x61, 0x4c, 0x1a,
+ 0x2a, 0x74, 0x54, 0xe9, 0xf2, 0xef, 0xf4, 0x75, 0xfc, 0x9d, 0x45, 0x14,
+ 0x83, 0xae, 0xd7, 0xd0, 0x9e, 0x27, 0x85, 0xe9, 0x11, 0x2d, 0xf5, 0x9a,
+ 0xf3, 0x2c, 0xb2, 0x55, 0x14, 0xc1, 0x7f, 0x7c, 0x8c, 0xa4, 0xc5, 0x53,
+ 0x4d, 0xe2, 0x0d, 0x5f, 0xb3, 0x91, 0xb3, 0x0e, 0xa8, 0x64, 0x0d, 0x4e,
+ 0x8b, 0x91, 0xc4, 0xa4, 0xb0, 0xae, 0x43, 0xad, 0x64, 0x5d, 0x8d, 0xbc,
+ 0x5f, 0xf4, 0x41, 0x7d, 0xc9, 0x03, 0x0e, 0xbf, 0xc3, 0xbf, 0xbe, 0xf5,
+ 0xff, 0x3a, 0xf0, 0xa6, 0x8e, 0xbe, 0x0b, 0x8f, 0xe7, 0x5f, 0xfd, 0x03,
+ 0xf8, 0xc6, 0xf3, 0x40, 0xfe, 0x75, 0x62, 0x2d, 0x50, 0xdb, 0xf1, 0xad,
+ 0x10, 0xd9, 0x0e, 0xbf, 0xe7, 0x51, 0xbd, 0x40, 0xbc, 0x8e, 0xbe, 0x9e,
+ 0x77, 0xdc, 0xeb, 0xbf, 0xd2, 0x1f, 0x58, 0x87, 0xfd, 0x38, 0xbf, 0x46,
+ 0x73, 0xa8, 0x75, 0xff, 0xe6, 0x7f, 0xee, 0x64, 0xe9, 0x9b, 0x23, 0x73,
+ 0xaf, 0xff, 0x7f, 0x0b, 0xe7, 0x22, 0x7f, 0x3b, 0xa8, 0x75, 0xfe, 0x96,
+ 0x77, 0x17, 0x0d, 0x3a, 0xf6, 0x2d, 0x5c, 0xeb, 0xfd, 0x9a, 0x1c, 0xf7,
+ 0x50, 0xea, 0x09, 0xe7, 0x08, 0xf5, 0x62, 0x73, 0x33, 0x1e, 0x74, 0x97,
+ 0xf4, 0xdf, 0x25, 0xec, 0x7f, 0xbf, 0xbd, 0x93, 0x0c, 0x2c, 0xf1, 0x01,
+ 0x5f, 0x9c, 0x43, 0xd8, 0x34, 0x40, 0x4c, 0x1b, 0x9b, 0xff, 0x93, 0x7d,
+ 0x07, 0x06, 0x04, 0x10, 0x75, 0xff, 0xc0, 0x6a, 0x9c, 0xcd, 0xf5, 0xfb,
+ 0xf8, 0xeb, 0xf4, 0x49, 0xf7, 0x64, 0xea, 0xc4, 0x58, 0x22, 0x0f, 0x11,
+ 0xed, 0x39, 0xd7, 0xef, 0x99, 0x32, 0x2c, 0xeb, 0xff, 0xc0, 0x8f, 0x9b,
+ 0x5e, 0x4d, 0x77, 0x77, 0x64, 0xea, 0x9c, 0xfe, 0x74, 0x53, 0x7f, 0xec,
+ 0x0f, 0x5d, 0x88, 0xec, 0x6e, 0x75, 0x2a, 0x11, 0xd7, 0xc8, 0x45, 0x2c,
+ 0x8e, 0xff, 0xc8, 0x2a, 0x70, 0x51, 0xa0, 0x13, 0xaf, 0xff, 0xcf, 0xbe,
+ 0xfa, 0x81, 0xf7, 0xd9, 0xba, 0x9e, 0xd1, 0xd5, 0x08, 0xce, 0xc3, 0x90,
+ 0x1e, 0x5f, 0x2e, 0x31, 0x67, 0x5f, 0xfb, 0x17, 0x0d, 0x4f, 0x70, 0x0b,
+ 0x3a, 0xf2, 0x6f, 0xa3, 0xad, 0x12, 0x3d, 0x9f, 0xcf, 0x6f, 0xf7, 0x26,
+ 0xd2, 0x0f, 0x90, 0xeb, 0xfd, 0xd4, 0xdf, 0xfe, 0x38, 0x4e, 0xbe, 0xdf,
+ 0xfe, 0x41, 0x57, 0x32, 0xc9, 0x55, 0x06, 0xed, 0x92, 0x3b, 0x85, 0x0a,
+ 0x60, 0xd0, 0xde, 0x7e, 0x4b, 0xe2, 0x2d, 0x65, 0x09, 0x0a, 0x56, 0xd9,
+ 0x0e, 0xb1, 0x0d, 0x6c, 0x94, 0x80, 0x90, 0x94, 0xe4, 0x3c, 0xfb, 0x1f,
+ 0x3b, 0x97, 0x0b, 0xcf, 0x8a, 0x01, 0x0e, 0x7b, 0xd3, 0xba, 0xce, 0xbd,
+ 0xe4, 0x64, 0xf1, 0x84, 0x5f, 0x78, 0x0f, 0xf4, 0xd1, 0x03, 0xee, 0x6a,
+ 0x69, 0xd1, 0x0c, 0x04, 0x5b, 0xca, 0xe9, 0xf9, 0xd7, 0x40, 0x0e, 0xbf,
+ 0x00, 0x7f, 0xfb, 0x23, 0xaf, 0xff, 0x87, 0x35, 0xf3, 0xef, 0x63, 0xf5,
+ 0xbc, 0xbe, 0x61, 0xbf, 0xd0, 0xad, 0x01, 0x19, 0x3b, 0x17, 0xaf, 0xfd,
+ 0xd0, 0x4f, 0x1f, 0x23, 0xd0, 0x13, 0xaf, 0x3f, 0x27, 0x3a, 0xe6, 0x59,
+ 0x3a, 0xff, 0x71, 0x33, 0x67, 0xd9, 0x30, 0xd3, 0x68, 0xc8, 0xe5, 0xff,
+ 0x91, 0x4f, 0x9a, 0x07, 0xeb, 0x89, 0x1d, 0x7f, 0xb5, 0x9e, 0x75, 0xe0,
+ 0x9d, 0x41, 0x4c, 0xd7, 0x8e, 0x9d, 0x4f, 0xf2, 0x15, 0xff, 0xc3, 0x8a,
+ 0x75, 0xe5, 0xf5, 0xf7, 0x83, 0xaa, 0x11, 0x07, 0x87, 0xd7, 0xff, 0x2d,
+ 0x6f, 0x2c, 0xe3, 0x5d, 0xda, 0x68, 0x86, 0x2f, 0xff, 0xff, 0x3e, 0xb0,
+ 0x71, 0xbd, 0x8d, 0xe5, 0xb7, 0x9d, 0x6a, 0x60, 0xba, 0x87, 0x56, 0x23,
+ 0x18, 0x09, 0xf4, 0x8a, 0xb9, 0xbb, 0x1e, 0xe8, 0xc3, 0x9e, 0xff, 0x2f,
+ 0xaf, 0x38, 0xc4, 0x8a, 0xbb, 0x40, 0x3a, 0xfe, 0x97, 0x5d, 0xc6, 0x0e,
+ 0xb4, 0x34, 0xf0, 0x37, 0x16, 0xbf, 0x71, 0xae, 0xed, 0x34, 0x41, 0x57,
+ 0xbb, 0x0b, 0x3a, 0xff, 0xd1, 0x3b, 0xfb, 0x99, 0x2d, 0xbc, 0x3a, 0xb1,
+ 0x11, 0xc8, 0x66, 0x23, 0x77, 0xee, 0xc2, 0xc1, 0xb9, 0xd7, 0xde, 0xd4,
+ 0x7e, 0x55, 0xe7, 0xe4, 0xe5, 0x5f, 0x00, 0x5d, 0x42, 0xaf, 0xf2, 0x4f,
+ 0x9e, 0xd4, 0x7e, 0x55, 0x15, 0x7f, 0x63, 0x63, 0xb0, 0xb2, 0xae, 0x65,
+ 0x92, 0xaf, 0xe1, 0x81, 0x9d, 0x38, 0x55, 0x62, 0x61, 0x4d, 0x22, 0x58,
+ 0xe7, 0x48, 0x7f, 0x33, 0x10, 0xa6, 0x4a, 0xfe, 0x8c, 0x5c, 0x9c, 0x29,
+ 0x83, 0xf4, 0xa9, 0x27, 0xf5, 0x31, 0x6f, 0x63, 0xa6, 0xa8, 0x56, 0xb5,
+ 0xd7, 0x27, 0x95, 0x61, 0x7f, 0x60, 0xe9, 0x07, 0x0e, 0xbd, 0xd0, 0x2c,
+ 0xea, 0xe9, 0xe2, 0xed, 0x14, 0xdf, 0xe7, 0x1c, 0xd7, 0x23, 0x47, 0x5f,
+ 0xc1, 0xc1, 0x7f, 0x68, 0xeb, 0x44, 0x8f, 0x6f, 0x46, 0x17, 0xee, 0x6f,
+ 0x2c, 0xf1, 0xd7, 0xff, 0xfd, 0xd4, 0xe6, 0x05, 0xd7, 0x83, 0xe1, 0x86,
+ 0x73, 0xda, 0x3a, 0xd0, 0x75, 0xfb, 0xb1, 0xb0, 0x30, 0xd3, 0xf2, 0xfd,
+ 0x8e, 0xb8, 0x8d, 0xbf, 0x42, 0x6a, 0xff, 0x6f, 0x2d, 0xb8, 0x6e, 0x2c,
+ 0xeb, 0xff, 0xff, 0x73, 0x91, 0xbc, 0xb7, 0xd2, 0x71, 0xbd, 0xcf, 0xbc,
+ 0x48, 0x09, 0xd5, 0x08, 0xa5, 0xc3, 0x6b, 0xff, 0xf3, 0x54, 0x7d, 0x67,
+ 0x24, 0x9d, 0x71, 0xde, 0x47, 0x5f, 0xf9, 0xb1, 0xed, 0x67, 0x93, 0x76,
+ 0x4e, 0xb3, 0xe2, 0x25, 0x14, 0x55, 0xa8, 0x4e, 0xab, 0xb0, 0xcd, 0x18,
+ 0x5a, 0xde, 0xf3, 0xfe, 0x75, 0xff, 0xf9, 0xde, 0x4f, 0xdf, 0x99, 0x38,
+ 0x3c, 0x07, 0xfa, 0x68, 0xbe, 0xef, 0x7f, 0x01, 0x3a, 0xff, 0xda, 0x41,
+ 0xde, 0x5c, 0x04, 0x68, 0xea, 0x99, 0x17, 0xfc, 0x65, 0xf0, 0xe5, 0xfe,
+ 0x89, 0xfb, 0x93, 0x42, 0xb9, 0xd6, 0x69, 0xd7, 0xff, 0xfb, 0xf4, 0xe2,
+ 0x9d, 0x85, 0xcd, 0x24, 0x1e, 0xc7, 0x20, 0xeb, 0x7b, 0x0f, 0xc7, 0x42,
+ 0x17, 0xde, 0x1c, 0x91, 0xd5, 0x07, 0x8e, 0x84, 0xf7, 0xfe, 0x14, 0x97,
+ 0xbb, 0x9c, 0x4d, 0x1d, 0x7f, 0x44, 0x87, 0x32, 0x73, 0xaf, 0xf3, 0x86,
+ 0x3f, 0x86, 0x74, 0x75, 0x74, 0xf7, 0x9c, 0xae, 0xfe, 0xdb, 0x56, 0xbf,
+ 0x3e, 0x77, 0x6c, 0xf1, 0x00, 0xdf, 0xef, 0x7f, 0xf4, 0x65, 0xdc, 0x3c,
+ 0x40, 0x37, 0x9f, 0x92, 0x3c, 0x40, 0x35, 0x87, 0xd4, 0x04, 0x2b, 0x9e,
+ 0x47, 0x88, 0x06, 0xf9, 0xc7, 0x79, 0x1e, 0x20, 0x1b, 0xfc, 0x8d, 0xee,
+ 0x7f, 0xfc, 0x1e, 0x20, 0x1b, 0xc8, 0x21, 0x3c, 0x40, 0x34, 0x14, 0x5b,
+ 0xac, 0x8b, 0xa5, 0xdb, 0x10, 0x2c, 0xa1, 0xe2, 0x01, 0xbd, 0xc8, 0xf1,
+ 0xe2, 0x01, 0xa3, 0xc4, 0x03, 0x7b, 0x6d, 0x3f, 0x3c, 0x40, 0x37, 0x42,
+ 0xcf, 0x10, 0x0d, 0x04, 0xf9, 0x70, 0x5d, 0x0b, 0x2f, 0x91, 0x61, 0x83,
+ 0xc4, 0x03, 0x7b, 0xce, 0xd3, 0xc4, 0x03, 0x7f, 0xe1, 0x79, 0x31, 0xd4,
+ 0x6b, 0xf0, 0xf1, 0x00, 0xdf, 0xfc, 0xfe, 0x04, 0xe8, 0x3e, 0xeb, 0xc8,
+ 0xf1, 0x00, 0xdc, 0xe1, 0x3c, 0x40, 0x37, 0xf8, 0x5d, 0x9d, 0x6a, 0x3f,
+ 0x3c, 0x40, 0x37, 0xe4, 0x51, 0xc7, 0xf3, 0xc4, 0x03, 0x72, 0x68, 0xf1,
+ 0x00, 0xd7, 0x0f, 0x5b, 0xc6, 0x97, 0xff, 0xba, 0x9e, 0xf6, 0x6b, 0xe7,
+ 0x12, 0x16, 0x78, 0x80, 0x6f, 0xde, 0x18, 0xde, 0x46, 0x88, 0x06, 0xef,
+ 0xe0, 0xf1, 0x00, 0xb0, 0x6d, 0x2f, 0xc9, 0x0b, 0x70, 0x9e, 0x20, 0x1b,
+ 0xe0, 0x38, 0xb4, 0xf1, 0x00, 0xde, 0x8e, 0x34, 0xf1, 0x00, 0xdf, 0xfb,
+ 0x37, 0xd0, 0x63, 0x07, 0xfd, 0x1e, 0x20, 0x1b, 0xf0, 0x1e, 0x52, 0x83,
+ 0xc4, 0x03, 0x7e, 0x76, 0xf6, 0x37, 0x3c, 0x40, 0x35, 0x88, 0xb2, 0xea,
+ 0x58, 0x0c, 0xee, 0xe7, 0xe7, 0x88, 0x06, 0xa4, 0xac, 0x94, 0x24, 0x59,
+ 0x09, 0x66, 0x91, 0x24, 0x22, 0xfa, 0x69, 0xf9, 0x96, 0x8b, 0x7d, 0x0d,
+ 0xa0, 0x17, 0xdf, 0xb3, 0xda, 0x7d, 0xcf, 0x10, 0x0d, 0xfe, 0x0c, 0x36,
+ 0x6e, 0x47, 0x8f, 0x10, 0x08, 0x4d, 0xa5, 0xee, 0x43, 0x27, 0x88, 0x06,
+ 0x9a, 0x7f, 0x3c, 0x50, 0xbf, 0xc0, 0x79, 0x4a, 0x3e, 0xac, 0xf1, 0x00,
+ 0xdf, 0x20, 0xcb, 0x47, 0x88, 0x06, 0xfe, 0x79, 0xa5, 0x9b, 0xc8, 0xf1,
+ 0x00, 0xd6, 0x23, 0x2f, 0xa4, 0x5f, 0xa0, 0x80, 0xb6, 0xff, 0xbb, 0x1a,
+ 0x63, 0x40, 0xe7, 0xe7, 0x88, 0x06, 0xc8, 0x78, 0x80, 0x6e, 0x79, 0xc2,
+ 0x7c, 0x9d, 0x48, 0xbb, 0x9f, 0x9e, 0x20, 0x1b, 0xf3, 0xfb, 0x49, 0xb9,
+ 0xe2, 0x01, 0xbf, 0x90, 0x41, 0x2c, 0xd1, 0xe2, 0x01, 0xa8, 0x44, 0x80,
+ 0x92, 0x78, 0xd2, 0xa1, 0x94, 0xb0, 0x18, 0x5a, 0xe4, 0x36, 0x10, 0xfe,
+ 0x61, 0xee, 0x42, 0x37, 0xa5, 0xae, 0x5b, 0xf9, 0x40, 0xa5, 0x6a, 0x5b,
+ 0xaf, 0xa5, 0x09, 0xed, 0xc2, 0x87, 0xec, 0x2f, 0xaf, 0x79, 0x19, 0x3c,
+ 0x61, 0x37, 0x9d, 0xda, 0x68, 0x80, 0x58, 0x4c, 0x57, 0x78, 0x76, 0x5f,
+ 0x28, 0xad, 0x02, 0xb3, 0xae, 0xd9, 0x39, 0xd7, 0xed, 0x83, 0x01, 0xe9,
+ 0xd5, 0x07, 0x82, 0x83, 0x37, 0xff, 0x48, 0x71, 0xbd, 0x4f, 0xff, 0x04,
+ 0xc7, 0x5d, 0xfc, 0x15, 0x65, 0x0a, 0xbd, 0xd8, 0x9c, 0xeb, 0x99, 0x64,
+ 0xaa, 0x43, 0xdb, 0x57, 0x16, 0x98, 0x45, 0x91, 0xcb, 0xcb, 0x4d, 0x14,
+ 0xc1, 0xe0, 0x5e, 0x40, 0x78, 0xeb, 0xff, 0xde, 0xd6, 0x28, 0x9c, 0xfb,
+ 0xff, 0xf1, 0xb9, 0xd5, 0x3b, 0x3a, 0x62, 0x44, 0x01, 0x84, 0xd3, 0x69,
+ 0x71, 0xc8, 0x9d, 0xc6, 0xa7, 0x20, 0xfe, 0x1c, 0x3e, 0x2d, 0xfa, 0x37,
+ 0x7f, 0xf8, 0x7d, 0xb7, 0x93, 0x49, 0xf9, 0x38, 0x60, 0xeb, 0xfb, 0xdf,
+ 0x76, 0x6c, 0x8d, 0x1d, 0x7f, 0xb3, 0x7f, 0x79, 0xe5, 0xa3, 0xaf, 0x0e,
+ 0xf2, 0x3c, 0x60, 0x15, 0x88, 0xdc, 0x44, 0xde, 0x19, 0xb9, 0x9d, 0xfa,
+ 0x69, 0x47, 0x27, 0x3a, 0xfa, 0x14, 0x85, 0x9d, 0x5c, 0x3c, 0xa5, 0x94,
+ 0xdf, 0xfa, 0x5a, 0xf8, 0x38, 0xb8, 0xe2, 0x87, 0x5f, 0xd2, 0x8e, 0x7f,
+ 0xf5, 0x67, 0x5f, 0xfd, 0xb0, 0x73, 0x5e, 0xc1, 0x96, 0x68, 0xeb, 0xe5,
+ 0xc0, 0x3c, 0x75, 0x61, 0xf2, 0x3a, 0x1d, 0xdd, 0x7c, 0x45, 0xa0, 0xc2,
+ 0x52, 0xff, 0xa1, 0xb0, 0xb4, 0x5f, 0xe8, 0x75, 0x70, 0xfa, 0x36, 0x8c,
+ 0x6f, 0xef, 0xac, 0xf1, 0x33, 0xa5, 0x5f, 0xfd, 0xf8, 0xa6, 0x6f, 0xe9,
+ 0xa4, 0xfc, 0x3a, 0xfa, 0x6e, 0xbc, 0xc7, 0x5f, 0x35, 0xf9, 0x39, 0xd7,
+ 0xec, 0x9a, 0x51, 0xb9, 0xd7, 0xba, 0x93, 0x1d, 0x78, 0x62, 0x45, 0x5f,
+ 0xf8, 0x7f, 0x4d, 0xad, 0xa0, 0x4a, 0x15, 0xce, 0xac, 0x3e, 0x17, 0x1a,
+ 0xad, 0xd3, 0x4f, 0xe2, 0x2f, 0x48, 0xc4, 0x8b, 0xc5, 0x1b, 0x4f, 0xb5,
+ 0x0a, 0xdf, 0x30, 0x89, 0x23, 0x5c, 0xe9, 0x2b, 0xc6, 0xfd, 0x7f, 0x6f,
+ 0xae, 0x72, 0x3c, 0x75, 0xfd, 0x2d, 0x29, 0xc7, 0x69, 0xd7, 0x87, 0xda,
+ 0x3a, 0xfd, 0xa0, 0x08, 0x1a, 0x75, 0x41, 0xf8, 0x21, 0x70, 0x06, 0xef,
+ 0xfe, 0xeb, 0x31, 0xcd, 0x63, 0x2f, 0xc5, 0x0e, 0xbf, 0x60, 0x43, 0x8b,
+ 0x3a, 0xff, 0xf7, 0xb7, 0x6a, 0x77, 0x6e, 0x3d, 0xdf, 0xba, 0x3a, 0xe5,
+ 0x4e, 0x8e, 0xbe, 0x14, 0xde, 0x47, 0x5f, 0xf2, 0x6f, 0xdc, 0x0f, 0x1d,
+ 0xa7, 0x54, 0x1e, 0xcf, 0x08, 0x6f, 0xfb, 0xb1, 0xc8, 0x6a, 0x0b, 0x4e,
+ 0xbe, 0xf2, 0x8f, 0xae, 0x1e, 0xbe, 0xd1, 0x0d, 0x49, 0x3c, 0x3e, 0x23,
+ 0x2c, 0x98, 0x0a, 0x0c, 0xc3, 0x2a, 0xfd, 0xb4, 0x05, 0xe0, 0x4e, 0xbf,
+ 0xf7, 0x73, 0x69, 0xc5, 0x4c, 0xdf, 0xc7, 0x5f, 0xf6, 0x37, 0xa8, 0x1e,
+ 0x81, 0x43, 0xaf, 0x7b, 0x1a, 0x75, 0x2c, 0xf5, 0x34, 0x73, 0x7a, 0x4b,
+ 0xfc, 0xea, 0x51, 0x1a, 0x9f, 0xc2, 0x57, 0xc4, 0x57, 0xfc, 0xa3, 0xfc,
+ 0x85, 0x8a, 0x28, 0x75, 0xff, 0x9f, 0x4b, 0x84, 0xe7, 0x11, 0x93, 0xad,
+ 0xa5, 0x0f, 0xdf, 0xa7, 0x57, 0xfd, 0x9e, 0xf2, 0x29, 0xec, 0x69, 0xd7,
+ 0xf8, 0x31, 0xbe, 0xb3, 0x7f, 0x1d, 0x7f, 0xd1, 0xe4, 0x6a, 0x06, 0x3c,
+ 0x75, 0xb4, 0x14, 0x51, 0x61, 0xc7, 0x0d, 0x2b, 0x74, 0xc0, 0x3d, 0x0c,
+ 0xbb, 0xfe, 0xf2, 0x4f, 0x1b, 0xff, 0xc8, 0x3a, 0xf6, 0xbd, 0x87, 0x5d,
+ 0x9a, 0xf8, 0x7a, 0xbf, 0x4e, 0xaf, 0xfe, 0xcf, 0x26, 0xf2, 0x18, 0x55,
+ 0x2a, 0xfd, 0xb3, 0xaf, 0xd9, 0xef, 0xdf, 0xc7, 0x54, 0x8f, 0xdf, 0x6d,
+ 0x42, 0xff, 0xfd, 0x1d, 0x7c, 0x18, 0xe2, 0x81, 0x03, 0xf2, 0x47, 0x54,
+ 0x93, 0x20, 0xf4, 0x2a, 0x36, 0x89, 0x6a, 0x17, 0x35, 0x71, 0x45, 0x21,
+ 0xfc, 0xf1, 0xd7, 0x02, 0x39, 0xfb, 0xee, 0xa3, 0xc8, 0xeb, 0xfd, 0x83,
+ 0x2c, 0xd7, 0xd5, 0x9d, 0x7e, 0x5e, 0xbf, 0x77, 0x3a, 0xbc, 0x7b, 0x5f,
+ 0x4c, 0xef, 0xfb, 0x98, 0x3f, 0x3b, 0x9b, 0xb2, 0x75, 0xff, 0x48, 0x41,
+ 0xff, 0xc6, 0xaf, 0xf3, 0xaa, 0x74, 0xc5, 0xa4, 0xf5, 0x84, 0x9b, 0x9d,
+ 0xdf, 0xf0, 0xc6, 0x6f, 0xec, 0xe4, 0x1d, 0x50, 0x7e, 0xae, 0x7f, 0x7e,
+ 0x7d, 0x81, 0x0c, 0x1d, 0x76, 0xb4, 0x75, 0xe6, 0x59, 0x64, 0xeb, 0xbf,
+ 0x72, 0x98, 0x2f, 0xeb, 0x87, 0xb7, 0xa3, 0x5b, 0xff, 0x66, 0x85, 0xd4,
+ 0x98, 0x52, 0x63, 0xaf, 0xef, 0xe2, 0x5d, 0xfb, 0xa3, 0xaf, 0x3f, 0xf8,
+ 0x55, 0x49, 0x32, 0xe5, 0xc2, 0x0f, 0xa4, 0x5f, 0x9f, 0x6d, 0x98, 0x5f,
+ 0x40, 0x50, 0x27, 0x5f, 0x83, 0xc4, 0x04, 0xe7, 0x5f, 0xe6, 0x70, 0x73,
+ 0x62, 0x70, 0xeb, 0xf8, 0x73, 0x7f, 0xfe, 0xc8, 0xea, 0x99, 0x11, 0x62,
+ 0x51, 0xe3, 0x3b, 0x9d, 0x67, 0x5f, 0xec, 0xd9, 0x8c, 0x32, 0xcb, 0x25,
+ 0x5f, 0xa6, 0x8c, 0xee, 0x8e, 0xa1, 0x3d, 0xff, 0xa7, 0x17, 0xf9, 0x53,
+ 0x00, 0x6f, 0x53, 0x87, 0x5e, 0x5b, 0xf8, 0xea, 0x99, 0x1d, 0x1d, 0x74,
+ 0x01, 0x1e, 0xc3, 0x6b, 0xf8, 0x76, 0x3a, 0xd1, 0x67, 0x5f, 0xb2, 0x69,
+ 0x44, 0x8e, 0xbf, 0xa7, 0x0c, 0x60, 0x84, 0xea, 0x85, 0x5a, 0xf2, 0x54,
+ 0x48, 0x55, 0xbc, 0x63, 0x1a, 0x40, 0xf1, 0x6f, 0xd2, 0x7b, 0xcf, 0xfa,
+ 0x1d, 0x7f, 0xc1, 0x10, 0x6b, 0x27, 0xc9, 0xce, 0xbd, 0x1c, 0x13, 0xaf,
+ 0xf6, 0x04, 0x5f, 0x48, 0x13, 0xad, 0xd3, 0xaf, 0x01, 0xe7, 0x13, 0xc0,
+ 0xd1, 0x85, 0x93, 0x88, 0x8d, 0xf2, 0xd5, 0x2d, 0x30, 0x97, 0x1b, 0x54,
+ 0xc3, 0x1a, 0xff, 0xf6, 0x05, 0xd7, 0x9b, 0xcb, 0x3f, 0xc0, 0x9d, 0x77,
+ 0x5c, 0xeb, 0xa6, 0xd1, 0xd7, 0xec, 0xd8, 0x82, 0x1c, 0x35, 0x9f, 0x45,
+ 0x6f, 0xdd, 0xcd, 0xfd, 0x07, 0x5f, 0xb6, 0x9e, 0x7f, 0xb2, 0x3a, 0xbe,
+ 0x26, 0x10, 0xc3, 0xae, 0x1f, 0x80, 0x9e, 0xf8, 0x39, 0xd7, 0x3a, 0xff,
+ 0xe8, 0xc1, 0x97, 0x70, 0x46, 0x19, 0x3a, 0xb8, 0x8a, 0x01, 0x40, 0xf1,
+ 0x05, 0xfe, 0xe6, 0xbb, 0x82, 0x9a, 0x3a, 0x90, 0xf8, 0x1c, 0xbe, 0xff,
+ 0xb0, 0x38, 0x30, 0x20, 0x83, 0xae, 0x86, 0x4e, 0xa9, 0xdd, 0x99, 0xf4,
+ 0xa5, 0xe8, 0x86, 0x5c, 0xae, 0x3e, 0x29, 0x08, 0x06, 0xca, 0xac, 0xdc,
+ 0xe5, 0x21, 0xb7, 0x31, 0x8f, 0x29, 0xf0, 0xcb, 0x8e, 0x03, 0xb3, 0x80,
+ 0x0e, 0xa9, 0xfc, 0x27, 0x86, 0x7b, 0x17, 0x51, 0xf2, 0xfa, 0x70, 0x94,
+ 0x11, 0xbc, 0xec, 0x94, 0x83, 0xf4, 0x83, 0x68, 0xd2, 0xff, 0xb3, 0x83,
+ 0x1e, 0x96, 0x74, 0xeb, 0xf8, 0x7f, 0xc0, 0xbc, 0x8e, 0xbf, 0xff, 0x03,
+ 0xda, 0x6f, 0x50, 0x63, 0x7d, 0x22, 0xe0, 0xeb, 0xfc, 0xd1, 0xc9, 0x49,
+ 0xf4, 0x75, 0xfc, 0xec, 0xe7, 0xff, 0x7c, 0x75, 0xf9, 0xe5, 0xf0, 0x28,
+ 0x75, 0xe9, 0x47, 0xe7, 0x5f, 0xbe, 0xcd, 0x28, 0x57, 0x2a, 0xa1, 0x38,
+ 0x8c, 0x36, 0x50, 0xb1, 0x15, 0x38, 0x63, 0xd3, 0x0f, 0x14, 0x7d, 0x1c,
+ 0xb3, 0x4e, 0xbf, 0xf9, 0x41, 0x03, 0xfd, 0xcd, 0x24, 0x09, 0xd7, 0xb6,
+ 0xd0, 0x27, 0x57, 0x0f, 0x85, 0x68, 0x77, 0xff, 0x6f, 0xe0, 0x2f, 0xb0,
+ 0x82, 0xe1, 0x3a, 0xf9, 0x4e, 0x3b, 0x27, 0x5b, 0xe9, 0xa2, 0x05, 0xb7,
+ 0x8d, 0x40, 0xa5, 0x78, 0xde, 0x32, 0x3f, 0x58, 0x88, 0x14, 0x5f, 0xbf,
+ 0xf2, 0x6d, 0xf5, 0x3e, 0xb1, 0xff, 0xf0, 0x55, 0xff, 0x0f, 0xb4, 0x0d,
+ 0xfc, 0x8c, 0x9d, 0x7f, 0x80, 0xfa, 0xcc, 0x15, 0x0e, 0xa8, 0x3e, 0xbe,
+ 0x9d, 0x5f, 0xfe, 0x45, 0x3e, 0x0b, 0xa9, 0xf3, 0x5f, 0xff, 0x07, 0x5f,
+ 0xe7, 0xee, 0xfa, 0x81, 0xf1, 0xd5, 0xa4, 0x41, 0x79, 0x42, 0xff, 0x9b,
+ 0xd4, 0x9a, 0x50, 0x32, 0x3a, 0xfa, 0x5d, 0xc9, 0xce, 0xbf, 0xe8, 0xdd,
+ 0x6f, 0xec, 0xdf, 0xc7, 0x56, 0xe7, 0xb6, 0x24, 0x57, 0xfd, 0x0d, 0xf0,
+ 0x3b, 0xc8, 0x64, 0xeb, 0xb8, 0xe7, 0x5f, 0xff, 0xd1, 0xcf, 0xf3, 0x62,
+ 0x6b, 0x58, 0x2d, 0x71, 0xfc, 0xea, 0xe1, 0xf8, 0x74, 0x56, 0xff, 0xcf,
+ 0xbe, 0xb3, 0xc8, 0xb7, 0x91, 0xd6, 0xf1, 0xd5, 0xf9, 0xe6, 0xfd, 0x3d,
+ 0xbf, 0xff, 0xf8, 0x1a, 0xeb, 0xcb, 0x52, 0x4f, 0x7d, 0xe4, 0x76, 0x3d,
+ 0xa7, 0xdc, 0xeb, 0xf4, 0x60, 0xfb, 0x6c, 0xeb, 0xf9, 0x37, 0xff, 0x8e,
+ 0x13, 0xac, 0xb3, 0xa9, 0x67, 0xcd, 0xd2, 0x81, 0x2e, 0xbd, 0x20, 0x04,
+ 0xeb, 0x9f, 0x7f, 0x87, 0x94, 0xe5, 0xd5, 0xc4, 0xd4, 0xf5, 0x19, 0x25,
+ 0xff, 0xfd, 0x83, 0x3e, 0xb5, 0x1f, 0xe7, 0x53, 0x8e, 0xcf, 0x8e, 0xa0,
+ 0xae, 0x48, 0x6f, 0x0a, 0x39, 0x88, 0xf9, 0x09, 0x35, 0x91, 0x76, 0x15,
+ 0x3f, 0xb7, 0xfa, 0x37, 0x86, 0x4a, 0xaa, 0x17, 0x76, 0x92, 0x75, 0x02,
+ 0xff, 0xff, 0xb9, 0x3e, 0x24, 0xce, 0xf2, 0xd4, 0x2c, 0x3d, 0x81, 0x69,
+ 0xd7, 0xc1, 0xe8, 0x27, 0x3a, 0xff, 0x05, 0xe5, 0x93, 0x80, 0x4e, 0xb4,
+ 0xf0, 0x7a, 0xb8, 0x47, 0x72, 0xa7, 0x0e, 0xac, 0x3c, 0x07, 0x27, 0xbf,
+ 0xbd, 0xb6, 0x0e, 0xe3, 0x4e, 0xbf, 0xdc, 0x8f, 0x27, 0xf1, 0x23, 0xaf,
+ 0x4e, 0x32, 0x3a, 0x95, 0x0c, 0x91, 0x68, 0x71, 0x42, 0x25, 0xc3, 0x13,
+ 0xb3, 0xbf, 0x6e, 0x58, 0x30, 0xfa, 0xd1, 0x07, 0x8c, 0x00, 0x65, 0x7f,
+ 0xe5, 0x47, 0xd8, 0x5b, 0x7a, 0xfb, 0xfe, 0x75, 0xfe, 0x94, 0xd8, 0x2f,
+ 0xdc, 0x3a, 0xff, 0x6c, 0x79, 0x83, 0x03, 0x39, 0xd7, 0xd0, 0x05, 0x4a,
+ 0x1d, 0x7b, 0xde, 0x83, 0xaf, 0xf2, 0x72, 0x27, 0x7e, 0x34, 0xeb, 0x7b,
+ 0x87, 0xe2, 0xe4, 0x9e, 0x1b, 0xbf, 0xfd, 0xc6, 0x8e, 0x6c, 0x1c, 0x8e,
+ 0x46, 0x8e, 0xbf, 0xcf, 0x37, 0x71, 0x79, 0xa3, 0xab, 0x0f, 0xeb, 0x62,
+ 0x45, 0xfc, 0x8a, 0x7b, 0x31, 0x67, 0x5f, 0xb0, 0x29, 0xcd, 0x1d, 0x7b,
+ 0xde, 0xdc, 0xeb, 0xff, 0xb7, 0x6a, 0x77, 0xe6, 0xd6, 0x75, 0x16, 0x75,
+ 0x7e, 0x7c, 0xde, 0x1d, 0xb8, 0x1c, 0x3a, 0xb4, 0x6e, 0x76, 0xc8, 0xed,
+ 0x13, 0xa3, 0xa5, 0x98, 0x62, 0xd4, 0x2a, 0xbb, 0xc8, 0x53, 0x24, 0x2b,
+ 0xba, 0x47, 0xe8, 0xc5, 0x6f, 0xfc, 0x29, 0xf7, 0x7c, 0xd9, 0xbc, 0x7d,
+ 0x3a, 0xff, 0xf2, 0x67, 0x03, 0x0c, 0xe7, 0x63, 0x7d, 0x1d, 0x7d, 0xf6,
+ 0x39, 0xf9, 0xd7, 0x3f, 0x0e, 0xbf, 0xbc, 0x93, 0xae, 0x1a, 0x75, 0x04,
+ 0xf0, 0xba, 0x2b, 0x76, 0x6d, 0x1d, 0x7d, 0xff, 0xd1, 0x91, 0xd7, 0x7e,
+ 0xe2, 0x6f, 0x3c, 0x31, 0x50, 0x88, 0xa0, 0x2f, 0x5d, 0xbc, 0xc7, 0x5f,
+ 0xbe, 0xfb, 0xf5, 0xe1, 0xd4, 0xb3, 0xc2, 0xfc, 0x62, 0xf3, 0x63, 0x47,
+ 0x5f, 0xf4, 0x9f, 0x9e, 0x18, 0x5e, 0x8e, 0xbf, 0xd0, 0x18, 0xe0, 0x23,
+ 0xf3, 0xae, 0x5e, 0xa6, 0x3e, 0x95, 0x9b, 0xdf, 0xfa, 0x1c, 0x73, 0xde,
+ 0x46, 0x7c, 0x75, 0x42, 0x62, 0x58, 0x46, 0x90, 0x84, 0x01, 0x7d, 0x2a,
+ 0x97, 0xaf, 0xa1, 0x1a, 0x52, 0xbb, 0x31, 0x65, 0xa8, 0x93, 0x24, 0xea,
+ 0x1e, 0x1e, 0x8d, 0xda, 0xfe, 0x80, 0x6e, 0x9b, 0xed, 0x1d, 0x7e, 0xc6,
+ 0x73, 0x7f, 0x1d, 0x6e, 0x7c, 0x3d, 0x94, 0x31, 0xbf, 0xfd, 0xac, 0x10,
+ 0x37, 0xb8, 0xb9, 0x9d, 0xa7, 0x5f, 0xe1, 0x53, 0xb0, 0xb5, 0x89, 0xd7,
+ 0xf2, 0xba, 0x46, 0xd0, 0x3c, 0x75, 0xfa, 0x26, 0xcc, 0x69, 0xd5, 0x88,
+ 0x8a, 0x43, 0x2e, 0x99, 0x5f, 0xfb, 0xb9, 0x32, 0x4c, 0x0d, 0xa0, 0x68,
+ 0xeb, 0xc9, 0xc5, 0x0e, 0xa4, 0x3d, 0xf1, 0x43, 0xbf, 0x46, 0xd7, 0x62,
+ 0x63, 0xaa, 0x47, 0x95, 0xa2, 0x0b, 0xff, 0x81, 0x32, 0x76, 0x37, 0x94,
+ 0x4d, 0x07, 0x5f, 0x82, 0xe3, 0x1d, 0x3a, 0xfe, 0x94, 0x6f, 0xec, 0xe9,
+ 0xd7, 0xff, 0xbd, 0xa4, 0xfe, 0x25, 0xac, 0xcd, 0xfc, 0x75, 0x4c, 0x7e,
+ 0xfa, 0x2d, 0xb2, 0x75, 0x17, 0xec, 0xc2, 0x72, 0xff, 0xfd, 0xc0, 0x73,
+ 0x90, 0x38, 0xa2, 0x77, 0xb9, 0xf4, 0xeb, 0xf8, 0x5d, 0x03, 0x02, 0x75,
+ 0xf4, 0xf1, 0xb5, 0x07, 0x5e, 0xd8, 0x0e, 0x9d, 0x7f, 0xf2, 0x2d, 0x35,
+ 0xd8, 0x4e, 0x01, 0x5c, 0xea, 0x84, 0x43, 0xa1, 0x23, 0x8f, 0x5f, 0xc3,
+ 0xa4, 0xd9, 0x01, 0x3a, 0xf0, 0xa2, 0x87, 0x5f, 0xde, 0x4e, 0x27, 0x80,
+ 0x75, 0xa1, 0x67, 0x8f, 0xf4, 0x6e, 0xfe, 0x07, 0xde, 0xe6, 0xfa, 0x3a,
+ 0xff, 0xff, 0xfd, 0xc8, 0xf0, 0xbb, 0x53, 0x53, 0x27, 0x1b, 0x1a, 0xf4,
+ 0x6f, 0x1f, 0x73, 0x47, 0x5f, 0xee, 0xe6, 0xf1, 0xc4, 0x59, 0xd7, 0xff,
+ 0xff, 0xfe, 0xd6, 0xb3, 0xdd, 0x75, 0xeb, 0x9c, 0x4d, 0xfc, 0xee, 0xa6,
+ 0x64, 0xc0, 0xf4, 0x33, 0xbc, 0x1d, 0x50, 0x9a, 0x88, 0x61, 0x06, 0xe6,
+ 0x57, 0xdf, 0xbe, 0xfa, 0x3a, 0xe6, 0x59, 0x3a, 0xb4, 0x6e, 0xd9, 0x23,
+ 0xbf, 0x27, 0x5f, 0x3a, 0x53, 0x06, 0x8a, 0xff, 0x81, 0xe8, 0x16, 0xab,
+ 0x7f, 0xac, 0xeb, 0xdd, 0x8f, 0xce, 0xa4, 0x3d, 0xa7, 0x3e, 0xbf, 0xdd,
+ 0x8f, 0x01, 0x60, 0xf1, 0xd5, 0x0b, 0xfd, 0x92, 0x29, 0x0c, 0x34, 0xf7,
+ 0x86, 0xba, 0xb9, 0x14, 0xd1, 0x82, 0x70, 0xb9, 0x6a, 0xdd, 0x85, 0x83,
+ 0x96, 0xfe, 0xe8, 0xa9, 0x29, 0x18, 0xe0, 0x75, 0x09, 0x1f, 0x42, 0x43,
+ 0x68, 0x82, 0xfd, 0x34, 0x4d, 0xd8, 0x3a, 0xef, 0xb0, 0x75, 0xe6, 0x59,
+ 0x64, 0xab, 0xe9, 0x7b, 0x1a, 0x53, 0x05, 0xfd, 0xfb, 0x02, 0x9f, 0xe8,
+ 0xf7, 0x7f, 0x57, 0x0f, 0x94, 0x4c, 0x6a, 0x11, 0xc9, 0xc2, 0x87, 0x84,
+ 0xdd, 0xde, 0xd1, 0xd7, 0xfd, 0xf3, 0xdd, 0x8f, 0x6b, 0xa8, 0x75, 0xb4,
+ 0x75, 0xfe, 0xf6, 0xf2, 0xec, 0x0c, 0xe7, 0x5f, 0xfb, 0x37, 0x92, 0x60,
+ 0x8e, 0x04, 0xeb, 0xf4, 0xeb, 0x06, 0xfe, 0x3a, 0xa1, 0x1f, 0x3b, 0x8b,
+ 0x70, 0xe8, 0x44, 0x34, 0x69, 0xe3, 0xbb, 0xfe, 0x18, 0x67, 0x48, 0x3b,
+ 0xc8, 0xeb, 0xa1, 0xa7, 0x50, 0x9e, 0x6e, 0xc3, 0x8b, 0xe9, 0xfe, 0xc2,
+ 0xb9, 0xd7, 0xfb, 0x41, 0x18, 0x67, 0x04, 0xea, 0xe1, 0xec, 0x78, 0x9e,
+ 0xa1, 0x34, 0x04, 0x85, 0x1b, 0xbd, 0xdf, 0xc3, 0xbe, 0xa6, 0xcf, 0x1d,
+ 0x7f, 0x27, 0x85, 0xff, 0xd1, 0xd7, 0xff, 0xbd, 0x36, 0x73, 0x1d, 0x71,
+ 0xd4, 0x09, 0xd7, 0xf0, 0x17, 0x9d, 0xdd, 0xce, 0xa5, 0x11, 0x42, 0x25,
+ 0x9a, 0x48, 0xbf, 0xfc, 0x81, 0x17, 0xdc, 0x73, 0xd8, 0x9f, 0x9d, 0x7f,
+ 0x47, 0xbb, 0x2d, 0x00, 0xeb, 0xf7, 0x5f, 0x99, 0xc3, 0xae, 0x03, 0x9d,
+ 0x4d, 0x37, 0x62, 0x4d, 0x7f, 0x72, 0x12, 0x4f, 0xa3, 0xad, 0x13, 0x9e,
+ 0x58, 0x90, 0x5f, 0xa7, 0x57, 0x4c, 0xdc, 0xeb, 0xf2, 0x6a, 0x27, 0x59,
+ 0xec, 0xfd, 0xbf, 0x43, 0xf3, 0xf0, 0x1e, 0xcf, 0xdb, 0x9e, 0x47, 0xb3,
+ 0xf6, 0xf8, 0x12, 0xcd, 0x1e, 0xcf, 0xda, 0x09, 0xe8, 0x09, 0x15, 0xfa,
+ 0x33, 0x58, 0x27, 0xb3, 0xf6, 0x8f, 0x67, 0xed, 0xcf, 0xe3, 0xd9, 0xfa,
+ 0xb2, 0xde, 0xd2, 0x13, 0xf9, 0x02, 0x45, 0xf6, 0x6d, 0xa7, 0xe7, 0xb3,
+ 0xf6, 0x8f, 0x67, 0xed, 0xdf, 0xc1, 0xec, 0xfd, 0xbf, 0xec, 0xfd, 0xf9,
+ 0x9b, 0x30, 0x27, 0xb3, 0xf6, 0xfe, 0xce, 0xa6, 0x81, 0x39, 0xec, 0xfd,
+ 0xaf, 0xd1, 0x46, 0x24, 0x7a, 0x46, 0xbe, 0xe4, 0xf1, 0xe3, 0xd9, 0xfb,
+ 0x47, 0xb3, 0xf7, 0x0d, 0x7d, 0xcc, 0xb2, 0x7b, 0x3f, 0x6a, 0x4a, 0xc3,
+ 0x82, 0x69, 0x90, 0x84, 0xde, 0x13, 0x5c, 0x27, 0x59, 0x8e, 0xa1, 0x75,
+ 0xe5, 0xf6, 0x49, 0xaf, 0x4a, 0x14, 0x2d, 0x9f, 0xa6, 0x11, 0x21, 0x7f,
+ 0xb5, 0x92, 0x94, 0x7b, 0x73, 0xab, 0x0f, 0xc3, 0x47, 0xb7, 0xfe, 0xc6,
+ 0x87, 0x38, 0xcb, 0xf6, 0x63, 0xae, 0x94, 0xe5, 0x5f, 0x4c, 0xef, 0xc3,
+ 0xaa, 0x74, 0x4c, 0x6e, 0x42, 0x27, 0xfb, 0x42, 0xf5, 0xc5, 0xd1, 0x27,
+ 0x9c, 0xd1, 0xbf, 0xcb, 0xd0, 0xe7, 0xb3, 0xf3, 0xaf, 0xf9, 0xb1, 0xf8,
+ 0x40, 0xfc, 0x91, 0xd7, 0xfe, 0x77, 0x9f, 0x16, 0xe3, 0xbc, 0x8e, 0xbf,
+ 0x32, 0x2e, 0xa6, 0xb0, 0xfd, 0xa6, 0x39, 0xa8, 0x47, 0x43, 0xc2, 0xa2,
+ 0xfc, 0x3e, 0xee, 0x4e, 0x75, 0xc1, 0x64, 0xea, 0x83, 0x7d, 0x84, 0xf7,
+ 0xff, 0xe9, 0x72, 0x36, 0x3c, 0xd0, 0x1e, 0xc2, 0xde, 0x63, 0xaf, 0xf6,
+ 0xd3, 0xe9, 0x35, 0x36, 0x1d, 0x5b, 0xa2, 0x33, 0x8a, 0xf5, 0x0c, 0xc1,
+ 0x99, 0x4a, 0x6c, 0xc3, 0x34, 0x86, 0x7a, 0xb9, 0x87, 0x11, 0xfb, 0x0b,
+ 0x37, 0x9d, 0x39, 0x18, 0xc5, 0x74, 0xc8, 0x08, 0x55, 0xdf, 0xff, 0xf2,
+ 0x75, 0xfb, 0x12, 0x63, 0x3f, 0x89, 0x68, 0x3d, 0x8e, 0x1d, 0x7f, 0xe5,
+ 0x23, 0x71, 0x8e, 0xf4, 0x0d, 0x3a, 0xff, 0xf0, 0x79, 0x18, 0x39, 0x24,
+ 0xee, 0x6c, 0x3a, 0xfe, 0x17, 0x53, 0xaf, 0x23, 0xaf, 0x32, 0xcb, 0x25,
+ 0x5e, 0xfb, 0x1f, 0x94, 0xc1, 0x7f, 0x7f, 0xcf, 0x2f, 0xbc, 0xcd, 0x8f,
+ 0xc3, 0xaf, 0xff, 0xdd, 0xc9, 0x7d, 0x11, 0xc9, 0xe6, 0x94, 0x72, 0x73,
+ 0xa8, 0x51, 0x27, 0xe3, 0xbb, 0xfe, 0xf3, 0x8e, 0x6b, 0x91, 0xa3, 0xaf,
+ 0xa5, 0x1f, 0xee, 0x75, 0xfd, 0xfc, 0x0e, 0x6f, 0xe3, 0xae, 0x7f, 0xfe,
+ 0x1e, 0x87, 0xd2, 0x3a, 0x74, 0x5c, 0x0c, 0x21, 0xaf, 0x6c, 0x8e, 0x1d,
+ 0x52, 0x56, 0x2c, 0x16, 0x6c, 0x3f, 0x5a, 0x47, 0xe9, 0x63, 0x0c, 0x1f,
+ 0x43, 0x6b, 0x61, 0x35, 0xc9, 0x39, 0xd7, 0xf8, 0x5a, 0x14, 0xd9, 0x01,
+ 0x3a, 0x82, 0x79, 0x20, 0x16, 0xb7, 0xe7, 0x5f, 0xf6, 0x42, 0xbf, 0xce,
+ 0xbe, 0x70, 0xeb, 0xfd, 0xfe, 0xda, 0x2c, 0x21, 0xc3, 0xaf, 0xfb, 0xdd,
+ 0xcd, 0x7c, 0xf2, 0x4e, 0x75, 0x41, 0xf8, 0xa1, 0xb5, 0xff, 0x0a, 0x01,
+ 0x53, 0xad, 0xb8, 0xf1, 0xd5, 0x24, 0xc6, 0xe6, 0x11, 0xec, 0x2b, 0x04,
+ 0x82, 0xf3, 0x2c, 0xb2, 0x58, 0x84, 0x17, 0xcd, 0x77, 0x69, 0x62, 0x10,
+ 0x30, 0x6b, 0x6f, 0x9f, 0x98, 0xc9, 0xd5, 0xc3, 0xe0, 0xd8, 0x7f, 0x79,
+ 0x96, 0x59, 0x2c, 0x41, 0xea, 0x2c, 0x41, 0xe6, 0x0d, 0x6d, 0xe6, 0x59,
+ 0x64, 0xeb, 0xda, 0x85, 0x0a, 0x60, 0xbf, 0xb2, 0xf1, 0x18, 0xad, 0x51,
+ 0xf2, 0x45, 0xff, 0xdd, 0x89, 0x27, 0xb3, 0xad, 0x85, 0x9d, 0x50, 0x7e,
+ 0xfb, 0x0d, 0x6f, 0xff, 0x67, 0x53, 0x9d, 0x7c, 0xd2, 0x3c, 0xe7, 0x5f,
+ 0x47, 0xa1, 0x67, 0x52, 0xcf, 0x9f, 0xc8, 0xf7, 0xf3, 0x2e, 0x10, 0x3f,
+ 0xd3, 0xaf, 0x85, 0x21, 0x43, 0xaf, 0x7d, 0x8f, 0xce, 0xa9, 0xcd, 0xf2,
+ 0xc8, 0x2f, 0xcd, 0x8e, 0xc2, 0xca, 0xbf, 0x0b, 0x88, 0xe1, 0x57, 0x63,
+ 0x4a, 0xb9, 0x96, 0x4a, 0xac, 0x3f, 0x6d, 0x13, 0x78, 0x8d, 0x91, 0x5b,
+ 0xfc, 0x3f, 0x63, 0xfe, 0xe6, 0xd1, 0x4c, 0x1b, 0xcb, 0xff, 0xd3, 0x87,
+ 0x8e, 0xd1, 0xcd, 0x9c, 0x4d, 0x1d, 0x50, 0x9f, 0xb6, 0x11, 0x23, 0x6b,
+ 0xc3, 0x50, 0x09, 0x17, 0xff, 0x47, 0xfa, 0xcc, 0x0b, 0x8b, 0xa8, 0x75,
+ 0xff, 0xf4, 0xb4, 0xcc, 0x73, 0xb0, 0x9d, 0x81, 0x43, 0xaf, 0xff, 0xb4,
+ 0x39, 0xbf, 0xef, 0xa7, 0xe2, 0x6f, 0xf9, 0xd5, 0xba, 0x27, 0x99, 0x4d,
+ 0xae, 0xa6, 0x0a, 0xf0, 0xe0, 0xbf, 0xb5, 0xf4, 0x20, 0x19, 0x1d, 0x7f,
+ 0x23, 0x43, 0x8f, 0xf9, 0xd7, 0xff, 0xfe, 0x89, 0xd8, 0xd7, 0xb5, 0xbf,
+ 0xc0, 0xe0, 0x61, 0xf9, 0x83, 0xf9, 0xd7, 0xe5, 0xe9, 0x97, 0xdc, 0xeb,
+ 0x68, 0x28, 0x99, 0xfa, 0xe1, 0x7f, 0x64, 0xd2, 0x4e, 0x68, 0xea, 0x86,
+ 0x4a, 0xa8, 0x61, 0x8f, 0x91, 0x9e, 0xa4, 0xa0, 0xce, 0x4a, 0x80, 0x78,
+ 0xd4, 0x55, 0x25, 0x02, 0x5f, 0xa8, 0x62, 0xf8, 0xae, 0xf3, 0x2c, 0xb2,
+ 0x55, 0xf7, 0xee, 0x21, 0x29, 0x82, 0xfe, 0xfb, 0xa8, 0xf2, 0x3a, 0xfb,
+ 0x9c, 0x45, 0x9d, 0x7b, 0x51, 0xe3, 0xaf, 0x0f, 0xb4, 0x86, 0xf2, 0x62,
+ 0x1b, 0xdf, 0x14, 0xdb, 0x3a, 0xf7, 0x9c, 0x27, 0x57, 0x0d, 0xee, 0x88,
+ 0xaf, 0xe6, 0xc7, 0xe9, 0xc5, 0x0e, 0xbf, 0xbe, 0xe7, 0x33, 0x26, 0x3a,
+ 0xfc, 0xfd, 0xf8, 0x18, 0x3a, 0xa4, 0x9d, 0x08, 0x4c, 0x71, 0x71, 0x1b,
+ 0xc4, 0x87, 0x45, 0xde, 0x2e, 0xbf, 0x3f, 0x39, 0x9b, 0x9d, 0x7f, 0xfb,
+ 0xdd, 0x47, 0xff, 0x38, 0x18, 0x19, 0x1d, 0x7f, 0xfb, 0x7f, 0x9b, 0xff,
+ 0x02, 0xd7, 0x9c, 0x5c, 0xea, 0x84, 0x5e, 0x61, 0x38, 0xa4, 0x5f, 0xa3,
+ 0x5f, 0x46, 0x47, 0x5f, 0xff, 0xfc, 0xe9, 0xe4, 0xeb, 0x53, 0xe4, 0x93,
+ 0xae, 0x3e, 0x96, 0x73, 0x0e, 0xbd, 0xdc, 0xda, 0x3a, 0xfd, 0xed, 0x7d,
+ 0xd7, 0xce, 0xa2, 0x35, 0xdb, 0xef, 0xe6, 0x75, 0xd7, 0x6c, 0x1d, 0x7f,
+ 0xff, 0xf2, 0x29, 0xbc, 0xbd, 0x83, 0xed, 0x7c, 0xd6, 0xb3, 0x98, 0x2f,
+ 0x23, 0xaf, 0xfe, 0x60, 0x23, 0x00, 0x6e, 0x28, 0x9c, 0x3a, 0xec, 0x64,
+ 0xeb, 0x64, 0x1e, 0xd6, 0x91, 0x2f, 0xf0, 0x7b, 0x13, 0x3b, 0xee, 0x75,
+ 0xee, 0xff, 0xb0, 0xea, 0xe1, 0xe9, 0x6d, 0x19, 0xd4, 0x91, 0x3a, 0xef,
+ 0x17, 0xff, 0x67, 0x3f, 0x5a, 0x6b, 0xee, 0xa3, 0x0e, 0xbc, 0xea, 0xfa,
+ 0x3a, 0xa4, 0x7c, 0x6e, 0x8b, 0x78, 0x38, 0xb3, 0xaf, 0xbf, 0xf6, 0x7e,
+ 0x75, 0x21, 0xbe, 0xe0, 0xdd, 0xff, 0x37, 0xa3, 0x1b, 0xa4, 0x74, 0xea,
+ 0x85, 0xd1, 0x69, 0x46, 0x3c, 0x12, 0xdc, 0x85, 0xaa, 0x22, 0x70, 0xb5,
+ 0xe3, 0x6a, 0x18, 0x42, 0x81, 0x7f, 0xe9, 0x05, 0xff, 0x9d, 0x02, 0x0f,
+ 0x6a, 0x7c, 0x64, 0xeb, 0xf6, 0xb1, 0x48, 0xd1, 0xd7, 0xf2, 0xbe, 0x90,
+ 0x77, 0x91, 0xd7, 0xfe, 0x7e, 0x6d, 0xa7, 0x71, 0xf7, 0xfc, 0xeb, 0xff,
+ 0xf2, 0x7a, 0x17, 0x9b, 0xfa, 0x17, 0xf7, 0x8f, 0xf9, 0xd7, 0xc8, 0x2e,
+ 0x13, 0xaf, 0xfb, 0x51, 0xcf, 0x43, 0x01, 0x43, 0xaa, 0x48, 0xae, 0x0a,
+ 0xbe, 0x87, 0xef, 0xff, 0x69, 0x39, 0x12, 0xec, 0x4c, 0x20, 0x50, 0xeb,
+ 0x9b, 0xb6, 0x75, 0xfc, 0xa7, 0xa3, 0xb1, 0xa3, 0xaf, 0xee, 0xa6, 0xfa,
+ 0x7d, 0xce, 0xa9, 0x1f, 0xa2, 0x0c, 0xfe, 0x5b, 0x7f, 0xe1, 0x79, 0xba,
+ 0xfc, 0xe2, 0x04, 0xeb, 0xc1, 0x41, 0x3a, 0xfe, 0x8f, 0x2a, 0x1e, 0x37,
+ 0x3a, 0xbe, 0x1e, 0x52, 0x0d, 0x54, 0x95, 0x86, 0xe1, 0x3b, 0x4c, 0x12,
+ 0x1d, 0xf3, 0x18, 0x72, 0x17, 0xcb, 0x2f, 0x66, 0x10, 0xf7, 0xe4, 0x5a,
+ 0xac, 0xab, 0xd5, 0xb3, 0xaf, 0xbe, 0xc3, 0x3a, 0x3a, 0xef, 0xfc, 0x75,
+ 0xf7, 0x39, 0x9a, 0x3a, 0xec, 0x98, 0xeb, 0x4b, 0xe1, 0xf9, 0x4e, 0x48,
+ 0xe2, 0xff, 0x48, 0x6f, 0xc9, 0xe7, 0x1c, 0x3a, 0xfd, 0xc0, 0xe6, 0x09,
+ 0xd7, 0xff, 0x2b, 0xa6, 0x76, 0x36, 0x6b, 0xb1, 0xb9, 0xd7, 0xf6, 0xfc,
+ 0x06, 0xfe, 0x91, 0xd4, 0xe8, 0x9d, 0xd1, 0x28, 0x12, 0x2f, 0xfb, 0x07,
+ 0x99, 0xac, 0x4e, 0x9d, 0x7f, 0xfd, 0x2f, 0x0e, 0x3f, 0x87, 0x3d, 0xec,
+ 0x64, 0xeb, 0xd3, 0xe6, 0xc3, 0xaf, 0xff, 0x7b, 0x59, 0x37, 0x63, 0x66,
+ 0x77, 0xb0, 0x75, 0xfd, 0xd0, 0xa6, 0xc8, 0x09, 0xd5, 0x87, 0xf2, 0xe9,
+ 0x77, 0xd9, 0xe4, 0xd1, 0xd7, 0xf2, 0xb1, 0x30, 0xab, 0x73, 0x80, 0xea,
+ 0xd1, 0xec, 0xf8, 0x82, 0xa4, 0xaa, 0x90, 0x30, 0xc1, 0x69, 0x7e, 0xe6,
+ 0xbc, 0x4d, 0x18, 0x4b, 0xf9, 0xe6, 0xf3, 0x39, 0xd3, 0xaf, 0xf6, 0x91,
+ 0x4e, 0xb8, 0xa1, 0xd7, 0xc9, 0xac, 0x0b, 0x9e, 0x6f, 0x87, 0x2f, 0xfc,
+ 0xea, 0xff, 0x83, 0x48, 0x3b, 0xc8, 0xeb, 0xff, 0xfb, 0xd9, 0xd4, 0x8f,
+ 0x27, 0xf1, 0x26, 0x19, 0x65, 0x92, 0xaf, 0xf7, 0x40, 0xeb, 0x0b, 0xac,
+ 0xea, 0x14, 0x48, 0x79, 0x7a, 0xf8, 0x39, 0x8a, 0x15, 0x7c, 0xff, 0xbf,
+ 0x8e, 0xbf, 0xee, 0x3b, 0x7e, 0x76, 0x3e, 0x89, 0xd7, 0x81, 0x1c, 0x3a,
+ 0xef, 0x68, 0x27, 0xad, 0x31, 0xdd, 0xe9, 0x08, 0x0d, 0x10, 0xcd, 0xee,
+ 0xc4, 0xe7, 0x5e, 0x65, 0x96, 0x4a, 0xbd, 0x82, 0xd2, 0x98, 0x2f, 0xef,
+ 0xfd, 0x93, 0xe0, 0x5e, 0x43, 0x13, 0x9d, 0x5f, 0x9f, 0x38, 0x95, 0x5f,
+ 0x38, 0xab, 0x55, 0x51, 0xd7, 0x2b, 0x55, 0x6a, 0x75, 0xfb, 0x3d, 0xe0,
+ 0x4e, 0x75, 0xa4, 0xad, 0x4f, 0x28, 0x48, 0xaf, 0x3a, 0xbc, 0x1d, 0x7e,
+ 0xc0, 0xf5, 0xd5, 0xce, 0xbf, 0x0e, 0x06, 0x16, 0x75, 0x42, 0xae, 0x19,
+ 0xc8, 0x82, 0x43, 0x8e, 0xfb, 0x97, 0xcc, 0x51, 0xc8, 0x51, 0x74, 0x89,
+ 0xdd, 0x00, 0x5b, 0xb0, 0x75, 0x92, 0x9b, 0xfd, 0x0b, 0xc4, 0xe4, 0xd2,
+ 0x3a, 0xf7, 0x92, 0x0e, 0xbb, 0x04, 0xea, 0x43, 0x5c, 0x01, 0xab, 0xff,
+ 0xf7, 0x5f, 0x9a, 0xc4, 0x17, 0xf6, 0x99, 0x81, 0x3a, 0xfc, 0x14, 0xe4,
+ 0x78, 0xeb, 0xb7, 0xfc, 0xeb, 0xf9, 0x71, 0xaf, 0xd1, 0xa7, 0x5e, 0xd4,
+ 0x29, 0xf9, 0xe2, 0xe8, 0x62, 0xff, 0x03, 0x39, 0xff, 0xe8, 0x27, 0x5f,
+ 0xfb, 0x16, 0x81, 0xe6, 0x05, 0xd6, 0x75, 0xf6, 0x2f, 0xe8, 0x4e, 0xae,
+ 0x9e, 0xf8, 0x9e, 0x5f, 0xfe, 0x40, 0xf7, 0xee, 0xb3, 0x8d, 0x77, 0x69,
+ 0xa2, 0x0c, 0xbe, 0x07, 0x71, 0xa7, 0x54, 0x8f, 0xe3, 0x6d, 0x5e, 0xf7,
+ 0x40, 0xae, 0x75, 0xff, 0xee, 0x3e, 0xcc, 0x16, 0xf5, 0x3f, 0xfb, 0xe3,
+ 0xaa, 0x11, 0x22, 0xa9, 0x25, 0x00, 0xfd, 0x6e, 0xa8, 0x93, 0xa6, 0xba,
+ 0x84, 0x97, 0xa3, 0x2a, 0xbf, 0xdf, 0xa7, 0x7b, 0x9f, 0xb9, 0xd7, 0xff,
+ 0xfc, 0xbc, 0xf7, 0x9f, 0x83, 0x1b, 0xcb, 0xef, 0x3f, 0x5a, 0x68, 0xeb,
+ 0xfe, 0x5a, 0x33, 0x82, 0x1e, 0xc1, 0xd7, 0x74, 0x07, 0x5f, 0xff, 0xa4,
+ 0x82, 0x1e, 0xe6, 0xff, 0x5c, 0x7c, 0x21, 0x3a, 0xf2, 0x32, 0xae, 0x75,
+ 0xfe, 0xcd, 0x9a, 0xf7, 0xa1, 0x67, 0x57, 0x0f, 0x4f, 0xa3, 0xf5, 0x09,
+ 0xc0, 0x63, 0x4a, 0x1b, 0xcc, 0x2d, 0xa8, 0x54, 0x5f, 0xed, 0xbc, 0xd6,
+ 0xde, 0x72, 0x0e, 0xbf, 0xfe, 0x18, 0x6f, 0xce, 0x62, 0x01, 0x53, 0x9b,
+ 0x58, 0x75, 0x49, 0x77, 0x64, 0x24, 0x18, 0xa4, 0x92, 0xa3, 0xff, 0x4b,
+ 0xd4, 0x76, 0x7e, 0x4e, 0xda, 0x37, 0xbf, 0xda, 0xd6, 0x0f, 0xfb, 0x78,
+ 0x75, 0xf0, 0xa6, 0xd4, 0x1d, 0x69, 0x8e, 0xbf, 0xb5, 0x83, 0xfe, 0xde,
+ 0x1d, 0x6d, 0x9f, 0x11, 0x2f, 0x86, 0xbf, 0x91, 0x68, 0x46, 0xff, 0x81,
+ 0xef, 0xc0, 0xb8, 0xcf, 0x1d, 0x7f, 0xf8, 0x67, 0xf9, 0x32, 0x0e, 0x07,
+ 0x05, 0x43, 0xaf, 0xe4, 0xdf, 0x6b, 0xb1, 0xe3, 0xaf, 0x7d, 0xc8, 0x3a,
+ 0xa1, 0x12, 0xea, 0xe9, 0x6e, 0x61, 0x7f, 0xff, 0xe7, 0x0e, 0x0b, 0xfb,
+ 0x59, 0xcf, 0xff, 0x8c, 0xdf, 0xda, 0x43, 0xaf, 0x47, 0x26, 0x3a, 0xbe,
+ 0x36, 0xbb, 0x31, 0x2d, 0x32, 0x78, 0x41, 0x06, 0x15, 0x39, 0x2b, 0xa9,
+ 0xb0, 0xbd, 0xdc, 0xdd, 0x25, 0xd9, 0xf6, 0x15, 0xef, 0x3c, 0x73, 0xfc,
+ 0x63, 0x42, 0x8e, 0x08, 0x68, 0x32, 0x63, 0xb6, 0xd7, 0x7b, 0x79, 0xf6,
+ 0x1d, 0x7f, 0x7c, 0x6f, 0x63, 0x7d, 0xa3, 0xaf, 0x7c, 0xfd, 0x93, 0xab,
+ 0x73, 0xd3, 0xf1, 0x9d, 0xfd, 0x8c, 0xe6, 0x0a, 0x87, 0x5f, 0x2d, 0xf3,
+ 0x47, 0x52, 0x1e, 0x63, 0x96, 0x5f, 0xff, 0x36, 0x35, 0xa8, 0x5e, 0x79,
+ 0x35, 0xd7, 0x3a, 0xff, 0x08, 0xc4, 0x97, 0x08, 0x75, 0xfe, 0xf2, 0x6c,
+ 0x4f, 0x4a, 0x0a, 0xb2, 0xce, 0xbf, 0xb0, 0x54, 0xe4, 0x30, 0x87, 0x87,
+ 0xf4, 0xce, 0xb1, 0x30, 0x54, 0x4d, 0xd3, 0x95, 0xf7, 0x01, 0xbc, 0x8e,
+ 0xbf, 0xc3, 0x21, 0xc5, 0xc3, 0x4e, 0xbc, 0xb0, 0xe1, 0xd5, 0x07, 0xdd,
+ 0x84, 0x6e, 0x61, 0x7b, 0x6c, 0x1e, 0x3a, 0xff, 0xf7, 0xa1, 0x68, 0x1c,
+ 0x15, 0x3b, 0x0b, 0x3a, 0x9a, 0x7c, 0xfe, 0x1f, 0xbf, 0xfe, 0x4f, 0x76,
+ 0x35, 0x1d, 0x84, 0x9e, 0x14, 0x3a, 0xfd, 0xef, 0x69, 0xff, 0x3a, 0xfd,
+ 0x0b, 0xf6, 0x34, 0xeb, 0x92, 0x73, 0xaa, 0x11, 0x64, 0x89, 0xdd, 0x28,
+ 0xf1, 0x35, 0xf9, 0x94, 0x0e, 0xd2, 0x1d, 0x7f, 0xdd, 0x89, 0x20, 0xe2,
+ 0xe0, 0xeb, 0xfe, 0xcf, 0x77, 0x16, 0x2f, 0xe3, 0xaf, 0xed, 0x89, 0xcd,
+ 0xe1, 0x5c, 0xeb, 0x08, 0x4f, 0xa3, 0x0d, 0xaf, 0xcb, 0x86, 0xce, 0x13,
+ 0xaf, 0xa5, 0x0b, 0x73, 0xaf, 0xdc, 0xfd, 0x69, 0xa3, 0xae, 0xf6, 0xb0,
+ 0xfc, 0x1c, 0xa3, 0xe9, 0x05, 0x42, 0x34, 0x41, 0x09, 0x6b, 0x68, 0xeb,
+ 0xfa, 0x27, 0xc1, 0x45, 0x0e, 0xae, 0x1b, 0xcd, 0x08, 0x5f, 0xfd, 0x02,
+ 0xfd, 0x8f, 0xd8, 0xe6, 0xb4, 0x55, 0x4e, 0xa8, 0xd8, 0x31, 0xb7, 0x63,
+ 0x1a, 0xc8, 0x6f, 0xf3, 0x87, 0x5a, 0x8e, 0x48, 0xeb, 0x81, 0x39, 0xd7,
+ 0xfb, 0x79, 0x6f, 0xa4, 0xf4, 0x1d, 0x79, 0x37, 0xd1, 0xd5, 0x87, 0xa0,
+ 0x86, 0x94, 0x88, 0x87, 0xeb, 0x3d, 0xd8, 0xd3, 0xaf, 0x73, 0x34, 0x77,
+ 0x8b, 0x5b, 0xff, 0xe0, 0xfc, 0x74, 0xcd, 0x44, 0xf8, 0x28, 0xa1, 0xd7,
+ 0xfb, 0x8b, 0x8d, 0xfc, 0xed, 0x3a, 0xb1, 0x10, 0x48, 0x9f, 0x7c, 0x8b,
+ 0x89, 0x8e, 0xbe, 0xc9, 0xc1, 0x23, 0xaa, 0x63, 0xc3, 0x64, 0x86, 0xf8,
+ 0x01, 0x0c, 0x1d, 0x50, 0x78, 0xae, 0x49, 0x76, 0x32, 0x75, 0x15, 0x7f,
+ 0x6b, 0xec, 0x72, 0x16, 0x55, 0x15, 0x45, 0x51, 0x54, 0x55, 0x48, 0xf8,
+ 0x10, 0x2b, 0xf2, 0xe0, 0x05, 0x6d, 0x85, 0x6d, 0x05, 0x5d, 0xdc, 0x2a,
+ 0xfe, 0x77, 0xf4, 0xd0, 0xb2, 0xbe, 0x16, 0xb6, 0x54, 0x95, 0x45, 0x51,
+ 0x55, 0x22, 0xd1, 0x02, 0xa8, 0xaa, 0x2a, 0x8a, 0xa2, 0xa8, 0xaa, 0x2a,
+ 0xa7, 0x37, 0x81, 0x0a, 0x40, 0xaf, 0xc2, 0xb4, 0x15, 0xb0, 0x2a, 0x8a,
+ 0xa2, 0xaa, 0x45, 0xa6, 0x82, 0xa8, 0xaa, 0x2a, 0x8a, 0xa2, 0xaa, 0x46,
+ 0xa3, 0xf0, 0xaf, 0x05, 0x6d, 0x05, 0x51, 0x54, 0x55, 0x15, 0x45, 0x54,
+ 0xe6, 0xa1, 0x40, 0xae, 0x05, 0x74, 0x2a, 0xca, 0x15, 0x45, 0x51, 0x54,
+ 0x55, 0x15, 0x41, 0x35, 0x1b, 0x85, 0x7e, 0x14, 0x00, 0xaa, 0x2a, 0x8a,
+ 0xa2, 0xaf, 0xdd, 0x8f, 0xf5, 0x85, 0x51, 0x55, 0x23, 0xcf, 0x68, 0x57,
+ 0x42, 0x9c, 0x2b, 0xf2, 0x7b, 0x34, 0xaa, 0x2a, 0x8a, 0xa2, 0xa8, 0xaa,
+ 0x91, 0xa8, 0xdc, 0x29, 0x02, 0xb6, 0x05, 0x51, 0x54, 0x55, 0x15, 0x45,
+ 0x54, 0x8d, 0x40, 0x42, 0xba, 0x14, 0x21, 0x56, 0xe9, 0x54, 0x55, 0x15,
+ 0x69, 0x15, 0x45, 0x6e, 0x58, 0x51, 0x54, 0x55, 0x15, 0x45, 0x54, 0xe7,
+ 0xcd, 0x20, 0xa5, 0x06, 0x9a, 0x35, 0x30, 0x57, 0xe1, 0x5e, 0x0a, 0xb6,
+ 0x15, 0x45, 0x51, 0x56, 0x91, 0x54, 0x56, 0xe5, 0x85, 0x15, 0x45, 0x54,
+ 0x1e, 0x94, 0x82, 0x90, 0x6b, 0x83, 0x4b, 0x0a, 0xa2, 0xa8, 0xaa, 0x2a,
+ 0x8a, 0xa2, 0xaa, 0x0d, 0x96, 0xe1, 0x5c, 0x0a, 0x58, 0x50, 0x85, 0x51,
+ 0x54, 0x55, 0x15, 0x5c, 0x2f, 0xb4, 0x15, 0xe0, 0xaa, 0x2a, 0x8a, 0xa2,
+ 0xa9, 0x65, 0xf0, 0x85, 0x78, 0x2a, 0xcb, 0x2a, 0x8a, 0xa2, 0xab, 0xf2,
+ 0xd0, 0x01, 0x54, 0x55, 0x15, 0x45, 0x51, 0x55, 0x06, 0xa2, 0x60, 0xae,
+ 0x85, 0x00, 0x2a, 0xa1, 0x7e, 0xa6, 0x77, 0x19, 0x1e, 0x84, 0xa3, 0x16,
+ 0xda, 0xd9, 0xba, 0x42, 0x33, 0xab, 0x9e, 0xcc, 0x73, 0xc8, 0x46, 0x2d,
+ 0x27, 0xa7, 0x0e, 0xcb, 0xf9, 0xd0, 0xbb, 0x69, 0x9f, 0xcc, 0x20, 0x79,
+ 0xd8, 0xca, 0xca, 0x5e, 0xd9, 0x67, 0xd2, 0x4d, 0xa4, 0x9b, 0xf4, 0x86,
+ 0x33, 0x45, 0x30, 0x9a, 0xb5, 0xe4, 0x85, 0x95, 0x7c, 0x8d, 0x7e, 0x1d,
+ 0x79, 0x03, 0x87, 0x59, 0x8d, 0xd1, 0x1b, 0xc3, 0x9e, 0x8d, 0x78, 0x82,
+ 0xd1, 0xb1, 0x94, 0x8f, 0xf6, 0x94, 0x05, 0x7f, 0xba, 0x8c, 0x87, 0x91,
+ 0x39, 0xd7, 0x93, 0x62, 0xa4, 0xea, 0xdd, 0x11, 0xd3, 0x1c, 0xf8, 0xd2,
+ 0xfd, 0x99, 0x33, 0xfd, 0x3a, 0xef, 0xe0, 0xeb, 0xfb, 0x8e, 0x3f, 0x63,
+ 0xf3, 0xae, 0x7e, 0x1d, 0x64, 0x39, 0xa5, 0xad, 0x9a, 0x75, 0x96, 0x75,
+ 0xdb, 0x6c, 0x22, 0x25, 0xf8, 0x2d, 0xd4, 0x37, 0x1e, 0xfa, 0x21, 0x7f,
+ 0xdd, 0x85, 0xe4, 0xd0, 0x33, 0x9d, 0x7f, 0xf7, 0xc7, 0x68, 0x7b, 0x1f,
+ 0xe0, 0xfe, 0x75, 0xdf, 0xc1, 0xd5, 0x87, 0xb9, 0xfa, 0x35, 0x62, 0x62,
+ 0x1f, 0xad, 0x02, 0x12, 0x97, 0xff, 0x08, 0xc4, 0xe3, 0x89, 0xb2, 0x36,
+ 0xce, 0xbd, 0x1b, 0xe8, 0xea, 0x73, 0xe1, 0xd2, 0x2d, 0xe7, 0xe4, 0x1d,
+ 0x7e, 0x4d, 0xb7, 0x1f, 0xce, 0xa9, 0x1e, 0x1a, 0xc6, 0xaf, 0xfb, 0xeb,
+ 0x87, 0x58, 0xb8, 0x57, 0x3a, 0xf6, 0x6e, 0xc9, 0xd7, 0xb7, 0xff, 0x38,
+ 0x7b, 0x22, 0x79, 0x7d, 0xb3, 0x39, 0x23, 0xaf, 0x05, 0xc4, 0xea, 0x43,
+ 0x7a, 0xe4, 0x77, 0xff, 0xd1, 0xf1, 0xf9, 0xc7, 0xfe, 0x18, 0x65, 0x96,
+ 0x4e, 0xa8, 0x4d, 0x81, 0xde, 0xf4, 0xe2, 0x01, 0xfa, 0x54, 0x37, 0x17,
+ 0xb0, 0xe7, 0x3b, 0x7c, 0xa3, 0x25, 0x0c, 0x27, 0x72, 0x12, 0x6d, 0x86,
+ 0xa6, 0xe7, 0x69, 0x29, 0x81, 0x5d, 0x16, 0x68, 0x5c, 0xf0, 0xdd, 0x70,
+ 0xac, 0xec, 0x2a, 0x5e, 0x95, 0xeb, 0xf9, 0x90, 0xc7, 0x9f, 0xa8, 0x4b,
+ 0xfa, 0x3c, 0x4b, 0xe4, 0x16, 0xc1, 0xd7, 0xf3, 0x2f, 0xce, 0x3e, 0xe7,
+ 0x5f, 0xff, 0xb5, 0xce, 0x24, 0xda, 0xe4, 0x79, 0x1a, 0x81, 0x3a, 0x96,
+ 0x8a, 0x21, 0x1f, 0x64, 0xba, 0xf9, 0x7e, 0x8d, 0x1d, 0x7f, 0xbd, 0x00,
+ 0x6f, 0x53, 0x87, 0x5f, 0xd8, 0xde, 0xc6, 0xf2, 0x3a, 0xfe, 0x5e, 0x91,
+ 0x4f, 0x32, 0x75, 0xfa, 0x37, 0xec, 0x48, 0xea, 0x14, 0x5a, 0xf8, 0xcb,
+ 0xe9, 0x6e, 0xd1, 0x7d, 0xdb, 0xf8, 0xeb, 0xf7, 0x9c, 0x41, 0x87, 0x5f,
+ 0xed, 0x62, 0xd3, 0xdd, 0x73, 0xad, 0x18, 0x7d, 0xa2, 0x2f, 0xe2, 0x5b,
+ 0xe9, 0x7c, 0x5a, 0x1d, 0x7b, 0x6b, 0x90, 0x75, 0xfe, 0xe2, 0x4c, 0x39,
+ 0xb1, 0xce, 0xbb, 0x7d, 0x7c, 0x3f, 0x48, 0x23, 0xe0, 0xf5, 0xff, 0x0c,
+ 0x3c, 0xfd, 0x8e, 0x7e, 0x75, 0xcf, 0xb0, 0xeb, 0xfa, 0x42, 0x92, 0xee,
+ 0x1d, 0x7e, 0x9d, 0x39, 0x12, 0x3a, 0xa6, 0x3e, 0x9e, 0x0b, 0x89, 0x5d,
+ 0xf6, 0x05, 0x14, 0x3a, 0xff, 0xf3, 0xa7, 0xa3, 0xda, 0xeb, 0xa7, 0x40,
+ 0x75, 0xf0, 0x88, 0x24, 0x75, 0xff, 0xbb, 0x1c, 0xfc, 0x71, 0x97, 0xfc,
+ 0xeb, 0xd9, 0x93, 0x1d, 0x6c, 0xe9, 0xed, 0x7e, 0x7f, 0x7f, 0x03, 0x80,
+ 0x5b, 0x89, 0xd7, 0xcb, 0x8c, 0x9c, 0xeb, 0xf6, 0x6c, 0x18, 0xdc, 0xea,
+ 0x43, 0xc9, 0xd1, 0x0d, 0xf4, 0x0f, 0x9a, 0x75, 0xa0, 0x2a, 0xa4, 0x32,
+ 0x14, 0x3c, 0x2f, 0xe9, 0x0b, 0xa3, 0x8b, 0xd6, 0x8a, 0x3c, 0xeb, 0xb6,
+ 0x43, 0x7f, 0x6b, 0x16, 0x9d, 0x83, 0xaf, 0x6f, 0x2d, 0x1d, 0x5b, 0x9e,
+ 0x47, 0x0a, 0xef, 0x6b, 0xf6, 0x4e, 0xa8, 0x3c, 0x1c, 0x23, 0xbe, 0x03,
+ 0xf2, 0x47, 0x5f, 0x40, 0x15, 0x3a, 0x2a, 0xfd, 0x26, 0x19, 0x65, 0x93,
+ 0xa8, 0x4f, 0x44, 0x04, 0xb7, 0xcf, 0xe5, 0xf8, 0xea, 0x0a, 0x2d, 0x31,
+ 0xcb, 0xf2, 0x1a, 0x85, 0xf3, 0xec, 0x30, 0x48, 0x6b, 0x2e, 0x15, 0xcf,
+ 0x0a, 0x6f, 0xe5, 0x66, 0x8c, 0x62, 0x60, 0x86, 0xa5, 0xe5, 0x65, 0x57,
+ 0xaa, 0x0e, 0xbd, 0x21, 0x73, 0xad, 0xba, 0xb2, 0x78, 0xb0, 0x57, 0x7f,
+ 0x47, 0x27, 0x8e, 0x4e, 0x75, 0xf8, 0x1f, 0xe0, 0xb4, 0xeb, 0xdc, 0x89,
+ 0x8e, 0xbe, 0x41, 0x79, 0x8e, 0xbf, 0xde, 0xcf, 0xb1, 0x32, 0x68, 0xea,
+ 0x92, 0x31, 0x78, 0x5c, 0xb2, 0x7e, 0x8e, 0x6c, 0x20, 0xbf, 0xe8, 0x4e,
+ 0xc2, 0xe7, 0xc6, 0x4e, 0xbf, 0xa3, 0xa9, 0x3b, 0x89, 0xd7, 0xfd, 0x38,
+ 0xe4, 0xbb, 0x9f, 0xe8, 0xeb, 0xff, 0x60, 0xef, 0x2d, 0x70, 0x11, 0xf9,
+ 0xd7, 0xec, 0xf6, 0xb1, 0x43, 0xa9, 0x0f, 0x99, 0x67, 0xf7, 0x83, 0x1b,
+ 0x0e, 0xbf, 0xfe, 0xc1, 0x18, 0x64, 0x23, 0x1b, 0xc9, 0x04, 0xeb, 0xff,
+ 0xcf, 0xf2, 0x69, 0x47, 0x27, 0xf8, 0xce, 0x74, 0xea, 0x0a, 0x2e, 0x7a,
+ 0x3a, 0x29, 0x97, 0xfc, 0xbe, 0xe7, 0xb0, 0x1c, 0x9c, 0xeb, 0xfe, 0x8f,
+ 0x67, 0x1a, 0xee, 0xd3, 0x45, 0xf1, 0x7e, 0xce, 0x46, 0xf2, 0x3a, 0xf7,
+ 0x61, 0x6d, 0x3e, 0xaf, 0x21, 0xdf, 0xff, 0x85, 0xbf, 0x3b, 0x09, 0xc4,
+ 0x5a, 0x6d, 0xc2, 0xce, 0xbc, 0xfc, 0x9c, 0xd1, 0x7f, 0xd4, 0x22, 0xcf,
+ 0x0c, 0xda, 0xaf, 0x7f, 0xff, 0xba, 0xfa, 0x48, 0xd7, 0xcf, 0x77, 0x17,
+ 0x8d, 0x7e, 0x1d, 0x74, 0x6d, 0x1d, 0x7d, 0xad, 0x3a, 0xce, 0xae, 0xa2,
+ 0x67, 0xf6, 0x0f, 0x0c, 0x5f, 0xff, 0xd2, 0x70, 0xb7, 0xa8, 0x39, 0xb1,
+ 0xe5, 0xa4, 0x09, 0xd7, 0xfd, 0x0b, 0xf8, 0x1c, 0xcf, 0xf4, 0x75, 0xff,
+ 0x26, 0x08, 0x54, 0x4c, 0xe1, 0xd4, 0x87, 0xe1, 0xb4, 0x75, 0x7f, 0x3f,
+ 0x37, 0x96, 0x78, 0xeb, 0xff, 0x7b, 0x49, 0xcf, 0x08, 0x1e, 0x47, 0x5f,
+ 0xfe, 0x5c, 0x6d, 0xe0, 0x07, 0x33, 0x64, 0x6e, 0x75, 0xff, 0xa3, 0x39,
+ 0x9c, 0xfd, 0x69, 0xa3, 0xaf, 0x3e, 0xfb, 0x47, 0x5f, 0xcf, 0xed, 0x46,
+ 0x4e, 0x75, 0x42, 0x67, 0xd8, 0x5a, 0x87, 0xa2, 0x99, 0xb0, 0xf5, 0x91,
+ 0xfb, 0xfe, 0x04, 0x2f, 0x58, 0xb8, 0x57, 0x3a, 0xff, 0xed, 0x60, 0xfb,
+ 0x5f, 0x76, 0x46, 0x6e, 0x75, 0xff, 0x33, 0xf6, 0x7d, 0x62, 0xe1, 0x5c,
+ 0xeb, 0xc9, 0xd4, 0x3a, 0xfa, 0x5c, 0x0c, 0x8e, 0xbe, 0x5f, 0x92, 0x73,
+ 0xab, 0x0f, 0x11, 0x08, 0xaf, 0xfe, 0xd9, 0xe5, 0x20, 0x65, 0x9d, 0x45,
+ 0x9d, 0x74, 0xfe, 0x3a, 0xff, 0x6c, 0xeb, 0xca, 0x30, 0x4e, 0xa8, 0x3c,
+ 0x9c, 0x17, 0xbf, 0xb1, 0x9f, 0xbd, 0x7f, 0x1d, 0x7f, 0xfe, 0xf7, 0xd9,
+ 0x46, 0xc4, 0x1f, 0xf8, 0x90, 0xbc, 0x2a, 0xfb, 0xbf, 0x77, 0xf1, 0xd7,
+ 0xec, 0x5e, 0x26, 0xc3, 0xaf, 0x4f, 0x32, 0xb9, 0xd5, 0x3a, 0x3c, 0xf0,
+ 0xbd, 0xaa, 0xe8, 0x4a, 0x02, 0x7b, 0xbd, 0x87, 0x5f, 0xb8, 0x93, 0xba,
+ 0xcd, 0x30, 0x9d, 0xf7, 0x81, 0x0e, 0x69, 0x84, 0xee, 0xfe, 0x0d, 0x40,
+ 0x9d, 0xfe, 0x17, 0x53, 0xd1, 0xcf, 0xcd, 0x40, 0x9d, 0xfe, 0xd6, 0x75,
+ 0x34, 0x09, 0xcd, 0x30, 0x9d, 0xd8, 0x13, 0x4c, 0x27, 0x73, 0x2c, 0x9e,
+ 0x61, 0x3a, 0xc4, 0xd2, 0xf7, 0x34, 0x42, 0xd5, 0x91, 0xe9, 0x03, 0x62,
+ 0x03, 0x24, 0x56, 0xf1, 0x66, 0x13, 0x30, 0x7c, 0xf6, 0x4d, 0xd3, 0xf7,
+ 0x66, 0x3c, 0x7a, 0x85, 0xcc, 0xf4, 0x3f, 0xea, 0xf3, 0x90, 0x0c, 0x23,
+ 0xb5, 0x18, 0x9f, 0xa5, 0x20, 0x5e, 0x1f, 0xd6, 0x75, 0xff, 0x40, 0x3c,
+ 0x29, 0xb3, 0xea, 0xce, 0xbc, 0x39, 0xac, 0x3d, 0x7e, 0x0e, 0x5e, 0x0f,
+ 0xf3, 0x1d, 0x50, 0xcc, 0xe4, 0x9e, 0x13, 0xe1, 0x86, 0xd6, 0x17, 0xb6,
+ 0x35, 0x64, 0x86, 0x3c, 0xc6, 0x3c, 0x86, 0x57, 0x63, 0x62, 0x15, 0x7d,
+ 0x1d, 0x7a, 0x74, 0x5b, 0x64, 0x33, 0x3e, 0x98, 0xdf, 0x83, 0x9c, 0x45,
+ 0x0e, 0xbf, 0xbb, 0x1f, 0x47, 0x7f, 0xce, 0xbf, 0x7b, 0x26, 0x45, 0x9d,
+ 0x7e, 0x8d, 0xff, 0xfe, 0x0e, 0xa8, 0x3d, 0x01, 0x27, 0xbf, 0x46, 0xc8,
+ 0x1f, 0x1d, 0x7e, 0x4d, 0x9e, 0x49, 0xce, 0xbf, 0x3c, 0xbd, 0x8d, 0x3a,
+ 0xfc, 0x39, 0xf7, 0x26, 0x3a, 0xff, 0xf6, 0x7f, 0xae, 0xa7, 0xcd, 0xe5,
+ 0x19, 0x39, 0xd7, 0xfd, 0xd7, 0x5f, 0x52, 0x37, 0x91, 0xd7, 0xf7, 0xd1,
+ 0x96, 0xdb, 0xce, 0x75, 0x49, 0x16, 0xe8, 0x9b, 0xf9, 0xc5, 0x4e, 0x9d,
+ 0x28, 0x48, 0x1a, 0x4f, 0xc2, 0x91, 0x26, 0xf4, 0x37, 0xef, 0xfd, 0x8f,
+ 0xd9, 0x90, 0x7b, 0x9b, 0x9d, 0x7f, 0x7f, 0x34, 0xa3, 0xda, 0x3a, 0xff,
+ 0xff, 0xfd, 0x9d, 0xc1, 0xff, 0x07, 0xdd, 0xce, 0xc6, 0x4c, 0x9c, 0x9b,
+ 0xa9, 0xbf, 0x8e, 0xbe, 0x18, 0xc6, 0x4e, 0xbe, 0x8d, 0xf4, 0xe7, 0x54,
+ 0x36, 0x4b, 0xb3, 0xa6, 0x04, 0xe3, 0x29, 0xa1, 0xe9, 0x0f, 0x25, 0x72,
+ 0x77, 0x94, 0x4a, 0x2b, 0xbe, 0x3d, 0x01, 0x7e, 0xc8, 0x41, 0x7d, 0x20,
+ 0xbf, 0xfe, 0x41, 0xc5, 0xc7, 0xd1, 0x04, 0x87, 0x16, 0x75, 0xff, 0x05,
+ 0x30, 0x41, 0x2c, 0xd1, 0xd7, 0xfd, 0xd4, 0x97, 0x5e, 0x48, 0xb3, 0xaf,
+ 0xfd, 0xa4, 0x1d, 0xe5, 0xe4, 0xd2, 0x1d, 0x58, 0x7e, 0x9e, 0x37, 0xbf,
+ 0x69, 0x70, 0x18, 0x3a, 0xa4, 0x99, 0xf6, 0x26, 0xae, 0x15, 0x5e, 0x21,
+ 0xbe, 0x18, 0xe4, 0x8e, 0xbf, 0xee, 0xc4, 0x90, 0x44, 0x1b, 0x9d, 0x7f,
+ 0xd1, 0x9e, 0xfb, 0xff, 0xf1, 0xb9, 0xd6, 0xe4, 0x22, 0x4f, 0x08, 0x16,
+ 0x6f, 0x7f, 0xff, 0xfb, 0xae, 0x9e, 0x90, 0x07, 0xda, 0xeb, 0xcb, 0xe8,
+ 0xc3, 0x79, 0x12, 0x3a, 0xff, 0xda, 0xfb, 0xe4, 0x10, 0x4b, 0x34, 0x75,
+ 0x2b, 0xa2, 0xdb, 0xae, 0xf7, 0xff, 0xf6, 0x6f, 0x9a, 0x71, 0xea, 0x47,
+ 0xba, 0x07, 0x59, 0xd5, 0x09, 0xb4, 0x3c, 0x3a, 0x84, 0x9a, 0xfe, 0x10,
+ 0x2d, 0x3b, 0x07, 0x5f, 0xff, 0x9c, 0x7c, 0xef, 0xd1, 0x8f, 0x69, 0x9c,
+ 0xe9, 0xd7, 0xfe, 0x9d, 0xc7, 0x5e, 0xea, 0x46, 0x8e, 0xbf, 0xe8, 0xff,
+ 0x41, 0x03, 0xf2, 0x47, 0x5e, 0xe6, 0xb4, 0x78, 0x80, 0xef, 0x9a, 0xee,
+ 0xd3, 0x44, 0x06, 0xc1, 0xa9, 0xbf, 0xb9, 0x1d, 0x8f, 0x99, 0x24, 0x50,
+ 0x71, 0x8a, 0x9d, 0x32, 0x3f, 0xb0, 0xdd, 0xaf, 0xd3, 0x9f, 0xf4, 0x6e,
+ 0xb7, 0xb6, 0x47, 0x4e, 0xac, 0x54, 0x24, 0x91, 0xe5, 0x7d, 0x2b, 0xbd,
+ 0xd7, 0x57, 0x3a, 0xfa, 0x3f, 0xdb, 0xc3, 0xab, 0xf3, 0xc2, 0xf0, 0xf5,
+ 0xf0, 0xfb, 0xf0, 0x1d, 0x7e, 0x5a, 0xb2, 0xac, 0xab, 0x2a, 0xc1, 0xd7,
+ 0xff, 0xf4, 0xb3, 0x49, 0xce, 0x22, 0xfe, 0xfb, 0xb8, 0xcf, 0x8e, 0xac,
+ 0x45, 0xda, 0x11, 0x39, 0xe5, 0xff, 0xe6, 0x70, 0x7d, 0x83, 0x2c, 0xd7,
+ 0xd5, 0x9d, 0x7f, 0xfa, 0x59, 0xbc, 0xbe, 0xc7, 0xec, 0x32, 0xcb, 0x25,
+ 0x5f, 0x96, 0xce, 0x26, 0xc3, 0xaf, 0x4b, 0x06, 0x63, 0xfb, 0xfa, 0xa5,
+ 0x50, 0x8f, 0xa7, 0x86, 0x2d, 0x42, 0xa2, 0xbe, 0xc3, 0x78, 0x63, 0x27,
+ 0xbf, 0xe4, 0x19, 0x69, 0x5a, 0xab, 0x0a, 0xca, 0xb0, 0x75, 0xf4, 0xda,
+ 0xc9, 0x8e, 0xbf, 0x7f, 0x1e, 0xc5, 0x73, 0xaf, 0xf4, 0x67, 0x1a, 0xee,
+ 0xd3, 0x44, 0x13, 0x7f, 0xd1, 0xec, 0xe3, 0x5d, 0xda, 0x68, 0xbe, 0x6f,
+ 0x0e, 0x68, 0x28, 0x80, 0x69, 0xed, 0x0a, 0x37, 0x76, 0x42, 0xaa, 0xff,
+ 0xe8, 0xea, 0x29, 0x9c, 0x9d, 0x60, 0xdc, 0xea, 0xc4, 0xdb, 0xd2, 0x30,
+ 0x0e, 0x94, 0xdf, 0xe0, 0x77, 0x6f, 0xa8, 0xde, 0x9d, 0x7f, 0xe9, 0xdf,
+ 0x7d, 0xbc, 0xf0, 0xbe, 0xc3, 0xaf, 0xff, 0xb3, 0xd0, 0x3e, 0xd6, 0x62,
+ 0x8a, 0x3c, 0x8e, 0xbf, 0xf6, 0x06, 0x25, 0x1d, 0xcf, 0xdc, 0xeb, 0xf9,
+ 0xe4, 0x09, 0x38, 0x4e, 0xbc, 0xcb, 0x2c, 0x95, 0x7e, 0xee, 0x35, 0xf8,
+ 0x53, 0x05, 0xfd, 0xff, 0xfe, 0x9b, 0x91, 0xb3, 0xe2, 0x8f, 0xf3, 0xec,
+ 0xda, 0xf9, 0x9b, 0xf8, 0xea, 0xf2, 0x29, 0x7e, 0x9b, 0x5f, 0xfe, 0x4e,
+ 0x27, 0x81, 0x9e, 0x75, 0xe0, 0x9d, 0x53, 0xaa, 0x28, 0x6a, 0x1a, 0xd3,
+ 0xbf, 0x3c, 0x18, 0x78, 0x78, 0x96, 0xff, 0xcb, 0x8d, 0xf4, 0x39, 0x3f,
+ 0xd9, 0x1d, 0x7f, 0xff, 0x93, 0xae, 0x3b, 0xcb, 0xec, 0xa0, 0x64, 0xeb,
+ 0xc0, 0x9d, 0x7f, 0xfb, 0x33, 0xa1, 0xec, 0x6b, 0x3a, 0x9f, 0x9d, 0x7f,
+ 0x94, 0xf9, 0x34, 0xa3, 0x9a, 0x3a, 0xa7, 0x4c, 0x82, 0x48, 0x21, 0x60,
+ 0x44, 0x8b, 0xf9, 0x5f, 0x25, 0xd8, 0xe1, 0xd7, 0xfb, 0xd0, 0x9d, 0x52,
+ 0x37, 0x3a, 0xff, 0xf6, 0xe3, 0xf1, 0xbd, 0x4f, 0xff, 0x8e, 0x48, 0xea,
+ 0x84, 0x58, 0x21, 0x7f, 0xd3, 0x3b, 0xe5, 0x7d, 0x4b, 0x61, 0xd7, 0xff,
+ 0xa2, 0x7f, 0xbd, 0x8d, 0xfd, 0x93, 0x88, 0x4e, 0xa7, 0x3f, 0x41, 0x27,
+ 0xbf, 0xd1, 0x83, 0xe5, 0x43, 0x2d, 0x3a, 0xff, 0x77, 0x36, 0x7c, 0xd4,
+ 0x9a, 0x75, 0x81, 0xa3, 0xed, 0xf1, 0xb5, 0xfe, 0x71, 0xf9, 0xf7, 0x9d,
+ 0x73, 0xaf, 0xd9, 0xc7, 0xdd, 0x93, 0xaf, 0xff, 0xf4, 0xf8, 0xc8, 0xe0,
+ 0x78, 0x80, 0x9c, 0x3d, 0x81, 0x9c, 0xea, 0x9d, 0x11, 0x5a, 0x28, 0xbc,
+ 0xcb, 0x2c, 0x95, 0x7f, 0xbe, 0xff, 0x03, 0x9b, 0xf8, 0xa6, 0x0b, 0xfb,
+ 0xff, 0xf9, 0x53, 0xf1, 0xbd, 0x40, 0x87, 0x19, 0xf9, 0xed, 0x64, 0xe7,
+ 0x57, 0x51, 0x54, 0x04, 0x5a, 0x44, 0xc4, 0x1e, 0x1d, 0xb5, 0x3b, 0x28,
+ 0x2e, 0x51, 0xde, 0x04, 0xd5, 0x25, 0x2f, 0x72, 0x37, 0xf5, 0xc3, 0xbb,
+ 0xb0, 0xa4, 0x18, 0x46, 0xe8, 0xa3, 0xd1, 0xe7, 0xdf, 0xfb, 0x10, 0x67,
+ 0x71, 0xf6, 0x2c, 0xeb, 0xff, 0x75, 0x19, 0x0f, 0x73, 0xdb, 0x78, 0x75,
+ 0xec, 0x1f, 0xce, 0xbe, 0xcf, 0x4d, 0x23, 0xaf, 0xfe, 0xda, 0x18, 0xda,
+ 0xd3, 0x8f, 0xdf, 0xf4, 0x75, 0x74, 0xfb, 0x5c, 0x8a, 0xff, 0xd9, 0xe8,
+ 0xe6, 0xbb, 0x03, 0xe3, 0xc4, 0x11, 0x7f, 0xa3, 0x38, 0xd7, 0x76, 0x9a,
+ 0x20, 0x86, 0x0f, 0x26, 0xfe, 0x7e, 0xf3, 0x88, 0xc9, 0xd7, 0xf2, 0xb8,
+ 0x59, 0x71, 0x91, 0xd4, 0x27, 0xba, 0x02, 0xdb, 0xff, 0xf4, 0x06, 0x69,
+ 0x20, 0xfa, 0x3f, 0x98, 0x52, 0x63, 0xa9, 0x45, 0x42, 0xbd, 0x84, 0x47,
+ 0xed, 0x43, 0x0a, 0xcd, 0x84, 0x37, 0xf7, 0x73, 0xde, 0x45, 0x9d, 0x7f,
+ 0x7b, 0xee, 0x75, 0xf7, 0x3a, 0xb7, 0x3d, 0xb1, 0x2c, 0xbf, 0xfd, 0xad,
+ 0x0b, 0xf9, 0xd7, 0xf6, 0x27, 0xc3, 0xaa, 0x0f, 0xb0, 0x04, 0x57, 0xf6,
+ 0x37, 0xee, 0xce, 0xe1, 0xd7, 0x42, 0x87, 0x5e, 0x0a, 0x09, 0xd7, 0x84,
+ 0x13, 0x9d, 0x7e, 0xeb, 0xcb, 0x04, 0xeb, 0xf9, 0x3c, 0x39, 0xd4, 0x3a,
+ 0xec, 0xef, 0xc3, 0xcf, 0x82, 0x5b, 0x9d, 0x9f, 0x88, 0xc9, 0xc1, 0x6e,
+ 0x8d, 0x79, 0xae, 0xa4, 0x9b, 0x26, 0x10, 0x8c, 0x3e, 0x6f, 0xff, 0xef,
+ 0x77, 0x35, 0xac, 0xc0, 0x72, 0x7c, 0x00, 0xf8, 0xeb, 0xfe, 0xec, 0x73,
+ 0xc3, 0x19, 0xb9, 0xd7, 0xff, 0xfc, 0x93, 0xc4, 0xb5, 0xce, 0x26, 0xf3,
+ 0x49, 0xf8, 0xbc, 0xdc, 0xeb, 0xdd, 0xc1, 0x0a, 0x28, 0x3a, 0x6f, 0x48,
+ 0x99, 0x6f, 0xa1, 0xf5, 0x7f, 0xe6, 0xf6, 0x33, 0x92, 0xd0, 0x16, 0x75,
+ 0xc9, 0xa3, 0xaf, 0xfb, 0x27, 0x7f, 0x7f, 0xf4, 0x64, 0x75, 0xfd, 0xf5,
+ 0x7a, 0x65, 0xf7, 0x3a, 0xa1, 0x1c, 0xf8, 0x50, 0xa1, 0xf7, 0x05, 0x7c,
+ 0x77, 0x7b, 0x99, 0xd3, 0xaf, 0x69, 0x16, 0x75, 0xa3, 0x86, 0xdb, 0xc3,
+ 0x77, 0xc9, 0x32, 0x32, 0x75, 0xff, 0xcb, 0x7d, 0xfe, 0xf9, 0x39, 0x00,
+ 0x54, 0x9d, 0x7f, 0xfe, 0x04, 0xe3, 0x19, 0xd6, 0x23, 0xd9, 0xd0, 0x70,
+ 0xeb, 0xef, 0x6b, 0xee, 0x82, 0x8c, 0x1c, 0x22, 0xfa, 0x95, 0x7e, 0xd2,
+ 0xf3, 0xda, 0x3a, 0xfc, 0xf2, 0x14, 0x83, 0xaf, 0xe8, 0x71, 0xf6, 0x09,
+ 0xd5, 0x24, 0xe9, 0xb2, 0x1c, 0xe8, 0x96, 0xb2, 0x71, 0x24, 0xbf, 0x9b,
+ 0xd4, 0xdb, 0x45, 0x0e, 0xbf, 0xfc, 0x9f, 0xc6, 0x97, 0x09, 0xce, 0x23,
+ 0x27, 0x5f, 0x2b, 0xf7, 0x27, 0x3a, 0xff, 0x40, 0x73, 0xc9, 0xd0, 0x1d,
+ 0x65, 0xc1, 0xeb, 0x04, 0x96, 0xff, 0xff, 0xcb, 0x71, 0xfe, 0x49, 0xa0,
+ 0x2f, 0xa9, 0x1e, 0xe8, 0x1d, 0x67, 0x5f, 0xff, 0x08, 0x3d, 0x24, 0xff,
+ 0xae, 0x9e, 0x75, 0x9d, 0x77, 0xc5, 0x73, 0xaf, 0xff, 0xce, 0x9e, 0x40,
+ 0xe0, 0x73, 0xc8, 0xb4, 0xe1, 0xd7, 0xb8, 0xfa, 0xc4, 0x5d, 0x71, 0x3b,
+ 0xa3, 0x77, 0x27, 0x9d, 0x36, 0x50, 0x46, 0x4b, 0x74, 0xa0, 0xeb, 0xff,
+ 0xd3, 0x87, 0xb1, 0xdc, 0xdf, 0xfc, 0xf6, 0x8e, 0xa7, 0x3e, 0x10, 0x0a,
+ 0xd0, 0x55, 0x88, 0xe1, 0x82, 0x42, 0x7d, 0xe3, 0x8c, 0x18, 0x4a, 0xdf,
+ 0xdc, 0x89, 0xd0, 0x7c, 0x75, 0xe0, 0xfd, 0x59, 0xd7, 0xe1, 0x80, 0xe4,
+ 0xc7, 0x5f, 0x68, 0x1c, 0x50, 0xeb, 0xf4, 0x77, 0xd1, 0x23, 0xaf, 0x82,
+ 0x0f, 0x6a, 0x0f, 0xbf, 0x72, 0x6f, 0xc8, 0xef, 0xdf, 0xe2, 0xe3, 0xa7,
+ 0x5e, 0x54, 0xf7, 0x0e, 0xa0, 0xa6, 0x8f, 0x85, 0x89, 0x08, 0xd1, 0x48,
+ 0x01, 0x3d, 0xee, 0x7d, 0xd1, 0xd7, 0x42, 0xb4, 0x3a, 0xff, 0xce, 0x2d,
+ 0xce, 0x35, 0xdd, 0xa6, 0x88, 0x46, 0xe9, 0x4e, 0x75, 0x42, 0x26, 0x3f,
+ 0x1e, 0x00, 0xde, 0xc4, 0x8b, 0xff, 0xff, 0xdd, 0xc0, 0x71, 0x4e, 0xa6,
+ 0xf1, 0xe0, 0x74, 0x73, 0x7f, 0x01, 0xf4, 0x75, 0xff, 0xd9, 0xbf, 0xdf,
+ 0x20, 0x82, 0x59, 0xa3, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x33,
+ 0x8b, 0x86, 0x06, 0x78, 0xe0, 0x70, 0x73, 0xda, 0x46, 0xe0, 0xfd, 0x9f,
+ 0x39, 0x1a, 0x17, 0x53, 0x58, 0x9f, 0xfe, 0x0f, 0xc5, 0xc3, 0x03, 0x3c,
+ 0x70, 0xea, 0x84, 0xd3, 0xf1, 0x16, 0xff, 0xef, 0x38, 0xcf, 0xbc, 0x86,
+ 0x33, 0x47, 0x5f, 0xfb, 0xee, 0x75, 0xd6, 0xc3, 0x2c, 0xb2, 0x75, 0xff,
+ 0xfb, 0x1b, 0xd8, 0x10, 0x8a, 0x4f, 0x82, 0x8a, 0x1d, 0x73, 0xbc, 0xe8,
+ 0x96, 0x92, 0x25, 0xff, 0xfd, 0x30, 0xc7, 0xfa, 0x6f, 0x53, 0x93, 0x0c,
+ 0x7f, 0xa3, 0xaf, 0xfe, 0xf7, 0x53, 0x67, 0x5e, 0x5c, 0x85, 0x0e, 0xbf,
+ 0x81, 0xe4, 0x00, 0xa8, 0x75, 0xfd, 0x8c, 0xe0, 0x83, 0xf3, 0xaf, 0xd2,
+ 0xcf, 0x47, 0xe7, 0x5d, 0x0b, 0x9c, 0xf5, 0x37, 0x2d, 0xbf, 0xff, 0xfb,
+ 0xf5, 0xbc, 0xba, 0xe9, 0xe4, 0x0e, 0x07, 0x3c, 0x8b, 0x4e, 0x1d, 0x5a,
+ 0x44, 0xf0, 0x0b, 0xef, 0xd3, 0xae, 0x03, 0x07, 0x54, 0x97, 0x3f, 0x43,
+ 0x1e, 0x46, 0xe4, 0x53, 0x43, 0x67, 0x85, 0xdd, 0x5d, 0xd2, 0x37, 0xa3,
+ 0x1f, 0xfa, 0x47, 0x7f, 0xa3, 0x5a, 0x89, 0xf1, 0x93, 0xaf, 0xf7, 0x71,
+ 0x79, 0xd0, 0x09, 0xd4, 0x13, 0xe4, 0xf1, 0x9d, 0x62, 0x63, 0x8f, 0x0f,
+ 0xab, 0xcc, 0xb2, 0xc9, 0x57, 0xfd, 0x9f, 0xbf, 0x33, 0x66, 0x04, 0xa6,
+ 0x0b, 0xfb, 0x99, 0x64, 0xab, 0xcc, 0xb2, 0xc9, 0x57, 0xf3, 0xce, 0x1e,
+ 0xc6, 0x8a, 0x60, 0xbf, 0xa1, 0x45, 0xeb, 0x29, 0x3b, 0x66, 0xf7, 0xe6,
+ 0xa0, 0x7e, 0xac, 0xa6, 0x0d, 0x9d, 0xe6, 0x59, 0x64, 0xab, 0xda, 0x8e,
+ 0x14, 0xc1, 0x7f, 0x7c, 0xe3, 0xbf, 0x8e, 0xb7, 0xe8, 0x8a, 0x5f, 0x2c,
+ 0xb2, 0x57, 0x7f, 0x04, 0x62, 0x4e, 0xd3, 0xaf, 0xda, 0x04, 0xfb, 0x62,
+ 0x75, 0xf8, 0x29, 0xb2, 0x02, 0x75, 0xf6, 0x0e, 0x2b, 0x9d, 0x5c, 0x3c,
+ 0xa5, 0x94, 0x52, 0x22, 0x5f, 0xeb, 0xad, 0xff, 0xdd, 0x79, 0x0b, 0xa9,
+ 0x30, 0xa4, 0xc7, 0x5f, 0xfd, 0x9c, 0x9e, 0x37, 0xd2, 0x0e, 0x7e, 0x75,
+ 0xfd, 0xdc, 0xd9, 0x9e, 0xd1, 0xd4, 0xd4, 0x5b, 0x7e, 0x89, 0xe4, 0x4a,
+ 0xe2, 0x79, 0xbd, 0x86, 0x10, 0xc3, 0x6a, 0xe9, 0xfc, 0x75, 0x42, 0xa5,
+ 0x5c, 0x94, 0x08, 0x27, 0x57, 0xb7, 0x56, 0xaa, 0xc1, 0xd7, 0xff, 0xb1,
+ 0x5d, 0xc7, 0xfc, 0x6c, 0x76, 0x16, 0x75, 0xf6, 0xba, 0x93, 0x15, 0x7f,
+ 0xcf, 0xbf, 0xb2, 0x60, 0x71, 0x43, 0xac, 0xd4, 0x3d, 0xd0, 0x11, 0x5f,
+ 0xe1, 0xcd, 0xe5, 0xa4, 0x50, 0xeb, 0xe7, 0x7e, 0x28, 0x75, 0x7c, 0x3d,
+ 0x49, 0xcc, 0xef, 0xfb, 0x31, 0xbf, 0xc6, 0x6f, 0x23, 0xaf, 0xa1, 0xd7,
+ 0xb0, 0xab, 0xff, 0xba, 0x8f, 0xff, 0xf1, 0xfc, 0x77, 0x47, 0x5f, 0xdd,
+ 0xc5, 0xad, 0xe4, 0x75, 0xe6, 0x59, 0x64, 0xab, 0xfc, 0x3e, 0xea, 0x40,
+ 0xce, 0x53, 0x05, 0xfd, 0xe8, 0xff, 0x24, 0x88, 0xcc, 0x4b, 0xaf, 0x26,
+ 0x09, 0xf6, 0x1a, 0x36, 0xc6, 0xa6, 0xa2, 0xb8, 0xc9, 0xaf, 0xf4, 0x7d,
+ 0xe7, 0x13, 0xda, 0x3a, 0xa1, 0x5a, 0xdc, 0x8a, 0x37, 0x85, 0x3a, 0x3d,
+ 0xcc, 0x4b, 0xd8, 0xe2, 0x44, 0xbe, 0xfd, 0xfe, 0x27, 0x54, 0x3a, 0xff,
+ 0xfb, 0x1b, 0x02, 0xfe, 0xd0, 0x40, 0xfc, 0x91, 0xd5, 0xb9, 0xfa, 0xac,
+ 0xa2, 0xf3, 0x63, 0x47, 0x5f, 0xfd, 0xf6, 0x59, 0xd7, 0xea, 0x73, 0x90,
+ 0x75, 0x61, 0xef, 0xfe, 0x37, 0x7e, 0x8f, 0x6b, 0x66, 0x1d, 0x7e, 0x07,
+ 0x14, 0xea, 0x1d, 0x50, 0x8f, 0x41, 0x84, 0x17, 0x88, 0xb6, 0xca, 0x2f,
+ 0xff, 0x93, 0x66, 0x08, 0x45, 0xd9, 0xc1, 0x75, 0x0e, 0xbf, 0xff, 0xe0,
+ 0xf5, 0x19, 0xcd, 0xa4, 0x5b, 0xfb, 0x40, 0x96, 0x6f, 0xe3, 0xab, 0x11,
+ 0x70, 0xe9, 0xd7, 0xfd, 0x33, 0x7a, 0x8b, 0x8e, 0x28, 0x75, 0xfa, 0x7f,
+ 0x80, 0x89, 0x8e, 0xb4, 0x8e, 0xbd, 0xf4, 0x66, 0x3a, 0xa4, 0x6b, 0xbf,
+ 0x10, 0xac, 0x45, 0xab, 0x9d, 0x69, 0x66, 0xa1, 0xd9, 0xbc, 0x4f, 0x28,
+ 0xf6, 0x52, 0x91, 0x43, 0x2a, 0x97, 0x29, 0x48, 0xca, 0x42, 0xd9, 0xa7,
+ 0x69, 0x29, 0x5a, 0x69, 0x50, 0x9c, 0x94, 0x90, 0xb9, 0x44, 0xbd, 0x96,
+ 0xbc, 0xf1, 0xcf, 0xff, 0x0e, 0x51, 0x9e, 0x58, 0xd4, 0xe1, 0x87, 0xa5,
+ 0xc8, 0x82, 0x3d, 0x96, 0x61, 0xf7, 0xf6, 0x1a, 0xd7, 0xb6, 0x40, 0x9d,
+ 0x7f, 0xfd, 0x82, 0xc7, 0x94, 0x4d, 0xf5, 0xdc, 0xfd, 0xce, 0xa9, 0x1f,
+ 0x68, 0x47, 0x2f, 0xf3, 0x8b, 0x73, 0xdd, 0x43, 0xab, 0x73, 0xd2, 0x59,
+ 0x15, 0x95, 0xa1, 0xd7, 0xfe, 0x71, 0xff, 0xe0, 0x40, 0xfc, 0x91, 0xd7,
+ 0xc8, 0x33, 0xc1, 0xd4, 0xae, 0x7c, 0x1c, 0x40, 0xa5, 0x5e, 0x89, 0xbc,
+ 0x76, 0xbd, 0x03, 0x39, 0xd7, 0xc9, 0xd4, 0x59, 0xd6, 0xea, 0x1b, 0xb9,
+ 0x86, 0xef, 0xe8, 0x6c, 0x6b, 0xc8, 0x75, 0xff, 0x47, 0xba, 0xff, 0xbe,
+ 0xfa, 0x3a, 0x82, 0x7c, 0x82, 0x57, 0x7f, 0xee, 0x7f, 0xf3, 0xa8, 0xd0,
+ 0x73, 0xf3, 0xaf, 0x4c, 0x0e, 0x1d, 0x7f, 0xe7, 0x4e, 0x66, 0xec, 0x32,
+ 0xcb, 0x27, 0x54, 0x22, 0x89, 0xd0, 0xf4, 0x3b, 0x7f, 0xfc, 0x31, 0x2f,
+ 0x9f, 0x7c, 0x82, 0x09, 0x66, 0x8e, 0xac, 0x4f, 0x35, 0xb0, 0x8b, 0xec,
+ 0x30, 0xff, 0x2e, 0xbf, 0xd0, 0x32, 0x1c, 0xcf, 0xce, 0xbf, 0xb3, 0x9a,
+ 0x18, 0x9c, 0xeb, 0xf9, 0xfd, 0xd7, 0x1f, 0xce, 0xbf, 0xf3, 0xfb, 0x26,
+ 0x78, 0x18, 0x98, 0xeb, 0x27, 0x0f, 0xa3, 0xa5, 0x97, 0x35, 0xa6, 0x8c,
+ 0x12, 0xa4, 0x8d, 0xe6, 0xc2, 0x53, 0xf2, 0x7b, 0xb0, 0x4e, 0xbf, 0xfd,
+ 0xe8, 0x16, 0xe7, 0xba, 0x9c, 0xfd, 0xa7, 0x50, 0x4f, 0x77, 0x05, 0x2f,
+ 0xf4, 0x2f, 0x5a, 0x71, 0x9c, 0xeb, 0xed, 0x60, 0xf8, 0xeb, 0xdb, 0x51,
+ 0xc3, 0xa9, 0xcd, 0xf0, 0x08, 0x2f, 0x79, 0xd5, 0xce, 0xbf, 0xde, 0xea,
+ 0x31, 0xfb, 0xa1, 0xd4, 0x14, 0xc0, 0xba, 0x42, 0x2e, 0x1e, 0x20, 0x00,
+ 0xf5, 0xf7, 0x51, 0xe4, 0x75, 0xe0, 0xbc, 0x8e, 0xb8, 0x1f, 0xc1, 0xbb,
+ 0xc2, 0x0b, 0xfe, 0x6e, 0x7a, 0x36, 0x20, 0xfe, 0x75, 0xff, 0xfc, 0x08,
+ 0xf6, 0xb0, 0x7e, 0x72, 0x10, 0x22, 0xf2, 0x3a, 0xfc, 0xde, 0xee, 0xea,
+ 0xe7, 0x5f, 0xfc, 0x81, 0x10, 0x7b, 0x50, 0x31, 0xa3, 0xa9, 0x11, 0xfc,
+ 0x27, 0x20, 0x59, 0xd8, 0x57, 0x7f, 0xf7, 0xef, 0xcc, 0xd9, 0x81, 0xe0,
+ 0xb2, 0x75, 0xff, 0xfc, 0x39, 0xa0, 0x7c, 0xce, 0xb8, 0xe4, 0xd2, 0x8d,
+ 0xce, 0xbf, 0x71, 0xae, 0xed, 0x34, 0x40, 0xd7, 0xf3, 0xcf, 0xfb, 0x88,
+ 0x49, 0x58, 0x3e, 0xf6, 0x68, 0x18, 0x7d, 0xdb, 0x66, 0x77, 0xba, 0xf2,
+ 0xf8, 0x8f, 0xe1, 0x86, 0x4d, 0x2d, 0x37, 0xef, 0x46, 0x89, 0x7f, 0xc3,
+ 0xff, 0x92, 0x75, 0xc3, 0x4e, 0xbf, 0x05, 0x5b, 0x70, 0xab, 0x67, 0x54,
+ 0x2a, 0x4f, 0xc8, 0xee, 0xd0, 0xa9, 0xce, 0x6f, 0xf6, 0x6f, 0xe0, 0xe6,
+ 0x28, 0x75, 0xfd, 0x9e, 0x81, 0x4f, 0xce, 0xbc, 0xfc, 0x9c, 0xd1, 0x82,
+ 0xdf, 0xf9, 0xf9, 0x83, 0xfe, 0xbd, 0xad, 0xce, 0xbf, 0xff, 0xff, 0xb3,
+ 0xdd, 0x71, 0x53, 0xe6, 0xb8, 0xef, 0xed, 0x98, 0x1f, 0x98, 0xb7, 0x1d,
+ 0xe4, 0x78, 0x82, 0xef, 0xfc, 0xee, 0xa3, 0x5c, 0x3f, 0x14, 0x64, 0xf1,
+ 0x05, 0xdf, 0xfd, 0xd4, 0xea, 0x40, 0xfb, 0xe2, 0x8c, 0x9e, 0x20, 0xbb,
+ 0xfd, 0x08, 0x3e, 0xf8, 0xa3, 0x27, 0x88, 0x2e, 0xfe, 0x5e, 0x07, 0xe2,
+ 0x8c, 0x9e, 0x20, 0xbb, 0xff, 0xfe, 0x71, 0x14, 0x5f, 0xcd, 0x37, 0xa9,
+ 0xc4, 0x52, 0x7c, 0x64, 0xf1, 0x05, 0xdd, 0xbf, 0xc0, 0xa7, 0x2e, 0xd4,
+ 0xfe, 0x29, 0xba, 0x10, 0x9f, 0x54, 0x2a, 0xc8, 0xe9, 0xf8, 0xca, 0x31,
+ 0xbf, 0xc9, 0x0a, 0x6b, 0xda, 0xdc, 0xeb, 0xe7, 0xe7, 0xee, 0x75, 0xff,
+ 0xdd, 0x4e, 0xa4, 0x0f, 0xbe, 0x28, 0xc9, 0xe2, 0x0b, 0xbf, 0xe9, 0xb4,
+ 0xd4, 0x9f, 0xe2, 0x8c, 0x9e, 0x20, 0xbb, 0xf7, 0xb5, 0x0b, 0xf8, 0xd4,
+ 0x4f, 0xfd, 0x53, 0xbf, 0xfd, 0xf1, 0xbd, 0x46, 0xc7, 0xb5, 0xf1, 0x46,
+ 0x4f, 0x10, 0x5d, 0xff, 0xff, 0xc2, 0x28, 0xbf, 0x80, 0xcf, 0x9a, 0x6f,
+ 0x53, 0x88, 0xa4, 0xf8, 0xc9, 0xe2, 0x0b, 0xac, 0x4c, 0x93, 0x74, 0x47,
+ 0x5d, 0xbf, 0xee, 0xa7, 0x11, 0x49, 0xf1, 0x93, 0xc4, 0x17, 0x7f, 0xfc,
+ 0xef, 0xbc, 0xb5, 0xd4, 0x08, 0x63, 0x90, 0x55, 0xff, 0xb2, 0x52, 0x06,
+ 0xb8, 0x33, 0xed, 0x9e, 0x20, 0xba, 0x6a, 0x39, 0x38, 0x8f, 0xa4, 0xeb,
+ 0xff, 0x35, 0x39, 0xe7, 0xff, 0x5f, 0x19, 0x3c, 0x41, 0x77, 0xf7, 0x53,
+ 0xbd, 0x4f, 0xcd, 0x00, 0x5d, 0xfb, 0x3f, 0xf8, 0xa3, 0x27, 0x88, 0x2e,
+ 0xec, 0xf3, 0x4f, 0xcf, 0xa7, 0x55, 0xba, 0x3b, 0xf5, 0x0c, 0x2b, 0xf9,
+ 0x78, 0x1f, 0x8a, 0x32, 0x78, 0x82, 0xef, 0xfc, 0xde, 0xa7, 0x11, 0x49,
+ 0xf1, 0x93, 0xc4, 0x17, 0x76, 0x7c, 0x74, 0x45, 0xe8, 0xfa, 0xff, 0x01,
+ 0x16, 0xe3, 0xbc, 0x8f, 0x10, 0x5d, 0xff, 0xb1, 0x36, 0x60, 0xe0, 0x5e,
+ 0x47, 0x88, 0x2d, 0x66, 0xfe, 0x82, 0xbb, 0xfb, 0xc3, 0x7f, 0xcd, 0x06,
+ 0x3e, 0x4d, 0x46, 0x29, 0xe8, 0xc7, 0xc1, 0x0b, 0x46, 0x5b, 0xae, 0xfe,
+ 0x0d, 0x10, 0x5b, 0x08, 0x8c, 0xb9, 0xda, 0x75, 0xb4, 0xd6, 0x4e, 0x2f,
+ 0xf4, 0x97, 0xaf, 0x1b, 0x5d, 0x2d, 0xa3, 0xaf, 0x44, 0xb6, 0x8e, 0xa8,
+ 0x36, 0xe2, 0x33, 0x53, 0xb2, 0xaf, 0x42, 0x67, 0xfd, 0x27, 0xc0, 0x5e,
+ 0xef, 0xfe, 0xc9, 0x0e, 0x7b, 0xa9, 0x9b, 0xf8, 0xeb, 0xf4, 0x7b, 0x5d,
+ 0x43, 0xaf, 0xfd, 0xa9, 0xa4, 0x00, 0xcd, 0x20, 0x04, 0xea, 0x91, 0xf4,
+ 0x78, 0x9a, 0xff, 0xe8, 0xde, 0x5f, 0x57, 0xaf, 0x46, 0xec, 0x9d, 0x7e,
+ 0x96, 0xd6, 0xd0, 0x27, 0x3a, 0xdd, 0x43, 0xf8, 0x74, 0x9b, 0xf7, 0x23,
+ 0x79, 0x68, 0xea, 0x91, 0xe7, 0x70, 0x9a, 0xff, 0xef, 0xc1, 0xad, 0xbc,
+ 0xe7, 0xeb, 0x4d, 0x1d, 0x7f, 0xbf, 0x07, 0x86, 0x3d, 0xa3, 0xab, 0xf3,
+ 0xfc, 0xd2, 0x4d, 0x42, 0x75, 0x39, 0x0e, 0x87, 0x84, 0xf5, 0xfc, 0xf2,
+ 0x8d, 0x8f, 0xd3, 0xaf, 0xb7, 0xd4, 0x6e, 0x75, 0xe5, 0xc4, 0x8e, 0xbf,
+ 0x60, 0x7a, 0x06, 0x4e, 0xaf, 0x87, 0xcc, 0xe4, 0x62, 0x37, 0x78, 0x2f,
+ 0xe3, 0xab, 0x87, 0x94, 0xe5, 0xf7, 0x93, 0x6f, 0x0e, 0xbc, 0xfc, 0xfc,
+ 0xeb, 0x6f, 0x06, 0xe7, 0xc3, 0xb7, 0xcc, 0xe7, 0x5c, 0xeb, 0xe5, 0x38,
+ 0x8c, 0x9d, 0x7e, 0x9d, 0xfb, 0x0a, 0xe7, 0x52, 0xb0, 0x79, 0xb8, 0x47,
+ 0x50, 0x9f, 0x92, 0x43, 0x75, 0xd6, 0xbf, 0x27, 0x16, 0xeb, 0xff, 0xc2,
+ 0x31, 0x3a, 0xfa, 0x9c, 0xe3, 0xc8, 0xeb, 0xfd, 0x3c, 0xf0, 0x3b, 0xe7,
+ 0x8e, 0xac, 0x3f, 0xc4, 0x48, 0xbf, 0xfb, 0x82, 0x0d, 0xfc, 0x39, 0x3b,
+ 0x89, 0xd7, 0x9f, 0x93, 0x9d, 0x77, 0xf0, 0x75, 0xf2, 0x42, 0xf0, 0xea,
+ 0x3a, 0xfe, 0x75, 0x3d, 0x1c, 0xfc, 0xea, 0x09, 0xb8, 0x10, 0xab, 0xff,
+ 0xfd, 0x08, 0x11, 0x80, 0x37, 0xd8, 0xd0, 0xc3, 0x7e, 0xac, 0xeb, 0xbf,
+ 0x83, 0xae, 0x85, 0x0e, 0xbf, 0xec, 0xf6, 0xa1, 0x7f, 0x72, 0x63, 0xaf,
+ 0xf6, 0xb3, 0xa9, 0xa0, 0x4e, 0x75, 0xcc, 0xb2, 0x55, 0xff, 0x0e, 0x6c,
+ 0x79, 0x69, 0x02, 0x75, 0x35, 0x3f, 0x24, 0x1c, 0xe0, 0xb2, 0xd5, 0xfa,
+ 0x41, 0xfb, 0x02, 0xa4, 0x58, 0x45, 0xb4, 0x74, 0xc9, 0x9f, 0xd1, 0x8b,
+ 0xcc, 0xb2, 0xc9, 0x56, 0x59, 0x4c, 0x17, 0xf7, 0xd3, 0x3b, 0xf0, 0xa6,
+ 0x11, 0xbd, 0xf6, 0x17, 0xd5, 0x3a, 0xb5, 0xb7, 0x96, 0x27, 0x7f, 0x7a,
+ 0x33, 0xb9, 0x39, 0xd7, 0x62, 0xce, 0xad, 0xcf, 0x07, 0x45, 0x95, 0x0d,
+ 0xf3, 0x8c, 0xa1, 0x7d, 0x92, 0x8c, 0x14, 0x48, 0xde, 0x30, 0xe4, 0x8e,
+ 0x57, 0x90, 0x85, 0xec, 0xb7, 0x97, 0xa5, 0x7f, 0x7e, 0x96, 0x32, 0x94,
+ 0xf5, 0x28, 0xab, 0xd0, 0xc9, 0x04, 0xb7, 0xbd, 0x8d, 0xb7, 0xf6, 0x7f,
+ 0xfa, 0x72, 0x47, 0x5c, 0xdc, 0x3a, 0x82, 0x78, 0x6e, 0x5d, 0x76, 0x32,
+ 0x75, 0xd1, 0xe3, 0xaa, 0x73, 0x56, 0xd1, 0x6b, 0x2c, 0xea, 0xc3, 0x65,
+ 0xe2, 0x2b, 0xfd, 0x24, 0x1c, 0x58, 0x3a, 0x75, 0xff, 0xb3, 0xda, 0xea,
+ 0x2d, 0xf3, 0x87, 0x54, 0x1f, 0x68, 0x98, 0xdf, 0x7c, 0xf4, 0x6c, 0x3a,
+ 0xfb, 0x17, 0x9e, 0x3a, 0xf7, 0x9d, 0x43, 0xaf, 0xff, 0xfe, 0x6b, 0xcc,
+ 0x09, 0x01, 0xbf, 0x3a, 0x9e, 0xf4, 0x6f, 0x13, 0xc6, 0x8e, 0xbf, 0xff,
+ 0xe5, 0x71, 0x77, 0xd9, 0x12, 0xec, 0x72, 0x78, 0xf6, 0x9e, 0x47, 0x5e,
+ 0x4d, 0xe6, 0x3a, 0xfd, 0x99, 0x38, 0x34, 0x75, 0xf7, 0x05, 0x3f, 0x3a,
+ 0xf9, 0x1a, 0xfc, 0x3a, 0xe8, 0xfc, 0xeb, 0xe0, 0x4e, 0x06, 0x3a, 0x6d,
+ 0xbe, 0x90, 0x52, 0x22, 0x53, 0xaa, 0xf7, 0xfd, 0xd7, 0xd7, 0x52, 0x77,
+ 0x13, 0xaf, 0x9e, 0x7f, 0xb2, 0x3a, 0x95, 0x4a, 0xf0, 0x21, 0xfa, 0x50,
+ 0x8d, 0xc2, 0x0d, 0xc9, 0x50, 0x83, 0x83, 0x8e, 0xed, 0xfb, 0x4e, 0x87,
+ 0x7d, 0x0b, 0xbf, 0xa4, 0x5b, 0x46, 0xf7, 0xf0, 0x80, 0x2b, 0x79, 0x1d,
+ 0x79, 0x27, 0x01, 0xd7, 0xe8, 0xfd, 0x37, 0xc3, 0xae, 0x5e, 0xc3, 0xac,
+ 0x18, 0x37, 0xe2, 0x4f, 0x7f, 0xfa, 0x43, 0x1f, 0x16, 0x30, 0xa7, 0x92,
+ 0x73, 0xaf, 0xce, 0xbc, 0xea, 0xce, 0xad, 0xcf, 0xc7, 0xc9, 0x77, 0xbd,
+ 0xc8, 0x3a, 0xff, 0x6b, 0xdb, 0x30, 0x70, 0x27, 0x54, 0x27, 0x1d, 0x22,
+ 0xcc, 0x5b, 0x48, 0x4b, 0x2c, 0x8d, 0xc6, 0xef, 0x3f, 0xcf, 0xa7, 0x5f,
+ 0x2d, 0x70, 0xb3, 0xaf, 0xff, 0x86, 0x5f, 0x30, 0x29, 0xad, 0xfc, 0x07,
+ 0xd1, 0xd7, 0xfb, 0xe8, 0xbf, 0xa5, 0x0a, 0x1d, 0x7d, 0x99, 0xbc, 0x8e,
+ 0xbd, 0xa4, 0x98, 0xeb, 0x28, 0x26, 0xf7, 0x44, 0x37, 0xff, 0x3c, 0xe3,
+ 0x1b, 0xa0, 0x46, 0x27, 0x3a, 0xb8, 0x7d, 0x42, 0x4f, 0x7e, 0xf9, 0xd8,
+ 0xe4, 0x8e, 0xaf, 0x89, 0xdb, 0x40, 0xfe, 0x10, 0xb5, 0x45, 0xe1, 0xb6,
+ 0xc9, 0x0d, 0xe5, 0xea, 0x0e, 0xbf, 0xa7, 0x9a, 0x4a, 0xae, 0x4e, 0x75,
+ 0xf2, 0xf1, 0xfa, 0x75, 0xd2, 0x9c, 0xeb, 0xdd, 0x0a, 0x1d, 0x7e, 0xee,
+ 0x24, 0xb4, 0x75, 0xff, 0xf7, 0x63, 0xeb, 0x1e, 0x17, 0xff, 0x5a, 0x8f,
+ 0xca, 0xbf, 0x71, 0xae, 0xed, 0x3c, 0x40, 0x97, 0xb5, 0x1b, 0x9d, 0x6f,
+ 0xf0, 0xf3, 0xf7, 0x33, 0xbd, 0xe4, 0x9c, 0xeb, 0xd3, 0xb8, 0x9d, 0x52,
+ 0x4c, 0xa0, 0x24, 0xdc, 0x85, 0x12, 0xca, 0x7c, 0x39, 0x7f, 0x0b, 0x5d,
+ 0x4e, 0xa1, 0xd7, 0x6d, 0x48, 0xeb, 0xef, 0x4e, 0xe2, 0x75, 0xe1, 0x75,
+ 0x0e, 0xbc, 0xa2, 0x78, 0xeb, 0xda, 0x7f, 0x1d, 0x4a, 0x1b, 0x7d, 0xc7,
+ 0x2e, 0xf9, 0xd3, 0xaf, 0xe5, 0xf9, 0x02, 0x08, 0x3a, 0xf2, 0xfc, 0xd3,
+ 0xad, 0xe8, 0x3c, 0x8c, 0x2c, 0xa9, 0xd3, 0x35, 0xc1, 0x96, 0x90, 0xf5,
+ 0x4b, 0xf2, 0x31, 0x60, 0xbb, 0x80, 0x3a, 0xff, 0x0b, 0xb3, 0xad, 0x47,
+ 0xe7, 0x5e, 0xdb, 0x75, 0x0e, 0xbf, 0xe8, 0x5c, 0xb2, 0x7c, 0x02, 0xa4,
+ 0xeb, 0xe7, 0xf2, 0xa6, 0x73, 0xab, 0x11, 0x02, 0x83, 0xee, 0x79, 0x79,
+ 0x96, 0x59, 0x3d, 0x5f, 0x57, 0x9c, 0x42, 0x5a, 0xbe, 0xac, 0x1a, 0xcb,
+ 0xf6, 0x48, 0x10, 0xa1, 0xd5, 0x09, 0xc1, 0x84, 0x5b, 0x90, 0xb4, 0xfd,
+ 0x67, 0xc7, 0x37, 0xff, 0xec, 0x14, 0x51, 0x8d, 0x7b, 0xa0, 0x79, 0x4a,
+ 0x0e, 0xa9, 0xd1, 0x4a, 0xa2, 0x85, 0xf6, 0x05, 0xe4, 0x75, 0xf9, 0xc4,
+ 0x51, 0x67, 0x5f, 0xf7, 0x53, 0x98, 0x8b, 0x85, 0x73, 0xaf, 0xc8, 0xb7,
+ 0x1c, 0x3a, 0xbe, 0x2f, 0x60, 0xab, 0x23, 0x70, 0x6b, 0x22, 0x00, 0x8b,
+ 0xe4, 0x68, 0x6a, 0x28, 0x24, 0x6c, 0x2f, 0x2a, 0x03, 0xf2, 0x51, 0x20,
+ 0x01, 0x26, 0xd9, 0xcd, 0xf9, 0x3d, 0x1e, 0xd1, 0x57, 0xcd, 0x8f, 0x68,
+ 0xab, 0x99, 0x64, 0xaa, 0x91, 0xef, 0xe1, 0x33, 0x24, 0x37, 0x63, 0x25,
+ 0x30, 0x6b, 0xef, 0xff, 0xbd, 0x0d, 0xcc, 0x1f, 0x75, 0x20, 0x67, 0x3a,
+ 0x8e, 0xac, 0x3d, 0x6d, 0x26, 0x57, 0xe8, 0x9e, 0x65, 0xf6, 0xff, 0xff,
+ 0x46, 0xc4, 0x1f, 0xfe, 0x7b, 0x58, 0xde, 0xb8, 0xfb, 0x47, 0x5f, 0xa5,
+ 0xd0, 0x47, 0x0e, 0xbf, 0xf9, 0xd7, 0xc8, 0xd8, 0x9b, 0x04, 0x1a, 0x3a,
+ 0xb7, 0x3e, 0xde, 0x93, 0xdf, 0xb0, 0x0b, 0x8d, 0x1d, 0x47, 0x5d, 0x93,
+ 0x70, 0xd8, 0x68, 0x9a, 0xff, 0x90, 0x0a, 0x9e, 0xc7, 0xd1, 0x9c, 0xeb,
+ 0xfe, 0x89, 0xe3, 0x7f, 0x0e, 0x4e, 0x75, 0x62, 0x29, 0x1a, 0x5a, 0x87,
+ 0xd7, 0xe7, 0x58, 0xc6, 0xe7, 0x54, 0xc9, 0xa5, 0xf2, 0x1e, 0xfd, 0x2e,
+ 0xbe, 0xce, 0xe4, 0xe7, 0x5e, 0x93, 0xf0, 0xeb, 0xf4, 0xb3, 0xd8, 0x12,
+ 0xaf, 0xa0, 0x46, 0x0e, 0xa9, 0x8f, 0x7f, 0xc3, 0x7f, 0x49, 0xaf, 0xbf,
+ 0xd2, 0xf8, 0x75, 0x28, 0x8d, 0x54, 0x84, 0x07, 0x8c, 0xaf, 0xf8, 0x73,
+ 0xb9, 0xf3, 0xb9, 0x39, 0xd7, 0xf0, 0x15, 0x29, 0xce, 0x61, 0xd7, 0xde,
+ 0x53, 0x3a, 0x75, 0xb4, 0x75, 0xc9, 0xf9, 0xd7, 0x75, 0x0e, 0xb8, 0x1a,
+ 0xf8, 0x6a, 0xe6, 0x16, 0xa7, 0x3e, 0xbf, 0xce, 0xee, 0xfe, 0x0e, 0xbb,
+ 0xf8, 0x3a, 0xfc, 0x09, 0x60, 0xb0, 0x86, 0xb3, 0xf1, 0x6a, 0x84, 0xc6,
+ 0x7f, 0x84, 0x68, 0xa7, 0x5f, 0xff, 0x60, 0xbe, 0xfa, 0x51, 0x47, 0xf8,
+ 0xd5, 0xfe, 0x75, 0xff, 0xde, 0xee, 0x2f, 0xec, 0x7f, 0x9b, 0xf8, 0xeb,
+ 0xfd, 0xbb, 0x53, 0x9f, 0x60, 0x27, 0x5f, 0x7e, 0xb7, 0x97, 0xc4, 0x68,
+ 0x69, 0x53, 0xc8, 0xf7, 0xf7, 0xeb, 0xfb, 0xaf, 0xb3, 0x9d, 0x76, 0x6e,
+ 0x75, 0x6e, 0x79, 0x5b, 0x66, 0x97, 0xdf, 0xf1, 0x38, 0x75, 0x42, 0x37,
+ 0x1e, 0x12, 0x8c, 0x93, 0x5f, 0x68, 0x1b, 0xf8, 0xeb, 0xb1, 0x93, 0xaf,
+ 0xfa, 0x37, 0xcf, 0xe3, 0x66, 0x4e, 0x75, 0x70, 0xf4, 0x7f, 0x16, 0xbf,
+ 0xf4, 0xd1, 0x3e, 0xb9, 0x8d, 0x89, 0xce, 0xbf, 0xb1, 0x78, 0x14, 0x64,
+ 0xeb, 0x97, 0x07, 0x52, 0xcf, 0x05, 0xcb, 0x2f, 0xe1, 0xc9, 0xba, 0x9e,
+ 0x3a, 0xfb, 0x33, 0xba, 0x3a, 0xb1, 0x1d, 0xcf, 0x08, 0x1f, 0x10, 0xed,
+ 0x16, 0x5e, 0x65, 0x96, 0x4a, 0xbf, 0x62, 0x82, 0x0d, 0x14, 0xc1, 0x7f,
+ 0x7e, 0xc6, 0x19, 0x65, 0x93, 0xaa, 0x0f, 0x8b, 0xc6, 0xf7, 0xfd, 0xae,
+ 0x40, 0x3c, 0x29, 0xb0, 0xeb, 0xff, 0x0e, 0x69, 0xbd, 0x46, 0xc0, 0x9d,
+ 0x7f, 0xff, 0x94, 0x65, 0xf8, 0xa3, 0x1a, 0xc9, 0x08, 0x1f, 0x58, 0x27,
+ 0x54, 0x23, 0x5b, 0x0e, 0x50, 0xee, 0xf9, 0x97, 0x19, 0x1d, 0x7f, 0xde,
+ 0x8d, 0xff, 0x7e, 0xf5, 0x0e, 0xb7, 0x4e, 0xac, 0x3c, 0x96, 0x9c, 0xde,
+ 0x65, 0x96, 0x4a, 0xbf, 0x91, 0xd4, 0xea, 0x78, 0xa6, 0x0b, 0xfb, 0xef,
+ 0x69, 0xf8, 0x75, 0xee, 0xc0, 0x4e, 0xa4, 0x37, 0x8e, 0x43, 0x7e, 0xcf,
+ 0xf3, 0x26, 0x3a, 0xda, 0xf8, 0x8f, 0xee, 0x20, 0x75, 0xe0, 0x47, 0xee,
+ 0x04, 0x82, 0x9d, 0x66, 0x46, 0xd1, 0x7e, 0x54, 0xf6, 0x27, 0x01, 0xd5,
+ 0xd5, 0x47, 0x43, 0x1e, 0xc8, 0x0d, 0x6f, 0x46, 0xc8, 0x3a, 0x90, 0xf4,
+ 0xc4, 0xde, 0xf0, 0xc6, 0xc3, 0xae, 0x54, 0xa1, 0xd7, 0x27, 0x4e, 0xb3,
+ 0xce, 0x6b, 0xb8, 0x33, 0x7d, 0xed, 0x01, 0x5c, 0xeb, 0xfd, 0x03, 0x21,
+ 0x48, 0xdc, 0xea, 0x86, 0x6e, 0x5c, 0x89, 0x72, 0x50, 0xda, 0x91, 0x86,
+ 0x34, 0xd5, 0x0e, 0x79, 0x1a, 0x4f, 0x63, 0xe1, 0x73, 0x4f, 0xdd, 0x06,
+ 0x31, 0x1d, 0x43, 0x13, 0xd2, 0xe1, 0x36, 0x10, 0x6d, 0xa5, 0x7d, 0x27,
+ 0xda, 0x25, 0xb9, 0x58, 0x43, 0xaf, 0xfd, 0x13, 0x7b, 0x6b, 0x51, 0x30,
+ 0x38, 0x75, 0xff, 0xd8, 0x9d, 0x80, 0xf4, 0x11, 0xbe, 0x8e, 0xbc, 0x15,
+ 0x3f, 0x3a, 0xfc, 0xbe, 0x71, 0xfc, 0x75, 0x7c, 0x3c, 0x58, 0x1e, 0xbf,
+ 0xfc, 0xd9, 0x9d, 0xbd, 0x89, 0x78, 0x71, 0x67, 0x5f, 0xff, 0x22, 0xf7,
+ 0x96, 0xbe, 0x60, 0x8e, 0x27, 0xe7, 0x5e, 0x4e, 0x80, 0xea, 0x56, 0x53,
+ 0xbc, 0x90, 0xd7, 0x10, 0xfb, 0x08, 0x87, 0x23, 0xf2, 0x4e, 0xc5, 0x0b,
+ 0x30, 0xac, 0x46, 0xc5, 0xf8, 0xa8, 0x85, 0xca, 0xb7, 0x1a, 0x42, 0xa9,
+ 0xb1, 0x5a, 0x46, 0x32, 0xab, 0xe3, 0x16, 0x56, 0xa7, 0x4a, 0xb0, 0x7c,
+ 0x53, 0x00, 0x27, 0x9d, 0x08, 0x95, 0x22, 0x4c, 0x34, 0x90, 0xcc, 0xb6,
+ 0x8e, 0x8a, 0x4b, 0x0e, 0x6d, 0x26, 0x23, 0x79, 0xf5, 0xf4, 0xa4, 0x67,
+ 0x4d, 0x4e, 0x08, 0xe5, 0x34, 0xa5, 0x73, 0xf1, 0x1d, 0xad, 0x9e, 0x9e,
+ 0xb9, 0xce, 0xfe, 0x92, 0x60, 0xa9, 0x86, 0xb0, 0xd6, 0x69, 0xfa, 0xb6,
+ 0xaf, 0xbe, 0xb4, 0x17, 0xa0, 0x9d, 0x1b, 0xd9, 0x29, 0x4d, 0x99, 0x41,
+ 0xfb, 0x73, 0xe3, 0xdf, 0x69, 0xf8, 0xdb, 0x52, 0xb6, 0x29, 0x88, 0xd9,
+ 0x8e, 0xa5, 0x9b, 0x1a, 0x65, 0xf9, 0x8f, 0xd7, 0x9e, 0x3a, 0xff, 0x31,
+ 0x9c, 0x6b, 0xbb, 0x4d, 0x17, 0x1d, 0xfe, 0x63, 0x38, 0xd7, 0x76, 0x9a,
+ 0x2e, 0xbb, 0xff, 0x98, 0x79, 0x31, 0x9c, 0x6b, 0xbb, 0x4d, 0x12, 0x8d,
+ 0x44, 0x6d, 0x6e, 0x32, 0x85, 0xd8, 0x4a, 0x54, 0x84, 0x7b, 0x4a, 0x12,
+ 0x3a, 0x15, 0x77, 0x17, 0xcd, 0x9a, 0x47, 0xf3, 0xbd, 0x14, 0xf8, 0xff,
+ 0x68, 0xfe, 0xff, 0xf3, 0x0b, 0x79, 0x31, 0x9c, 0x6b, 0xbb, 0x4d, 0x12,
+ 0xd5, 0xff, 0x2a, 0xee, 0xa2, 0xbb, 0xc6, 0xfb, 0x47, 0x5f, 0xb8, 0xd7,
+ 0x76, 0x9a, 0x23, 0x7b, 0xff, 0x3c, 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x89,
+ 0x7e, 0xfe, 0x8f, 0x7d, 0xeb, 0xf8, 0xeb, 0xfd, 0x9f, 0x78, 0xa7, 0x41,
+ 0xa3, 0xac, 0xc2, 0xb5, 0x4c, 0x97, 0x11, 0x16, 0x67, 0xd4, 0xa1, 0x2e,
+ 0xbf, 0xcc, 0x67, 0x1a, 0xee, 0xd3, 0x45, 0x57, 0x72, 0x6d, 0x1d, 0x7c,
+ 0x8b, 0x7d, 0x87, 0x52, 0x86, 0xeb, 0xc3, 0x17, 0x87, 0x69, 0x93, 0xaf,
+ 0xe7, 0xec, 0xc3, 0x01, 0x3a, 0xff, 0xef, 0x76, 0x34, 0x2e, 0x05, 0x4a,
+ 0x70, 0xeb, 0xd1, 0x2c, 0x3a, 0x82, 0x88, 0xcd, 0xcb, 0x26, 0x46, 0xbf,
+ 0xe5, 0x30, 0x73, 0x7f, 0x3a, 0xce, 0xb8, 0x28, 0x75, 0xfd, 0x9c, 0x6b,
+ 0xbb, 0x4d, 0x12, 0x05, 0x7c, 0x3c, 0xd6, 0x05, 0x6f, 0xda, 0x71, 0x7d,
+ 0xce, 0xb8, 0x10, 0x75, 0x48, 0xf8, 0x37, 0x25, 0xe1, 0x35, 0xfe, 0x94,
+ 0x72, 0x78, 0xe4, 0xe7, 0x5f, 0xee, 0x4e, 0xb8, 0x19, 0x68, 0xea, 0x83,
+ 0xe7, 0xc3, 0x4b, 0xec, 0x9d, 0xc2, 0x75, 0xff, 0xec, 0x9b, 0xae, 0xbf,
+ 0x76, 0x3c, 0x05, 0x9d, 0x53, 0xab, 0x06, 0x09, 0x16, 0x42, 0xad, 0x43,
+ 0x27, 0x87, 0x28, 0xc2, 0x5f, 0xc4, 0x1f, 0x48, 0x6f, 0xfe, 0x1c, 0x9d,
+ 0x8d, 0xb8, 0x11, 0xcf, 0x1d, 0x4c, 0x23, 0x23, 0x90, 0x83, 0xbf, 0xcc,
+ 0x67, 0x1a, 0xee, 0xd3, 0x45, 0x91, 0x7f, 0x98, 0xce, 0x35, 0xdd, 0xa6,
+ 0x8b, 0x5e, 0xff, 0xf6, 0x7d, 0x89, 0xd8, 0xc9, 0xbc, 0x18, 0x13, 0xaf,
+ 0xf3, 0x19, 0xc6, 0xbb, 0xb4, 0xd1, 0x72, 0x5f, 0xb8, 0xd7, 0x76, 0x9a,
+ 0x2e, 0xcb, 0xff, 0x3c, 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x8a, 0x3a, 0xcc,
+ 0x61, 0xfe, 0xac, 0xce, 0xf8, 0x62, 0x4b, 0x3a, 0xd2, 0x3a, 0xfd, 0xc6,
+ 0xbb, 0xb4, 0xd1, 0x4a, 0xdf, 0xf3, 0x7a, 0x93, 0x76, 0x27, 0xc3, 0xaf,
+ 0xff, 0x76, 0x27, 0x8e, 0xa6, 0xc7, 0x0f, 0x50, 0xe6, 0x0d, 0xcd, 0xd2,
+ 0x63, 0x11, 0x8f, 0x33, 0x65, 0x6e, 0x98, 0x3b, 0xc3, 0x5e, 0xff, 0xce,
+ 0x9e, 0x90, 0x02, 0xe3, 0xf9, 0xd6, 0x60, 0x29, 0xc6, 0xae, 0x32, 0x7e,
+ 0x94, 0xd4, 0xec, 0x9b, 0xb9, 0x46, 0xf9, 0xba, 0xb2, 0x4e, 0x23, 0xac,
+ 0xa7, 0xf3, 0xf1, 0x3f, 0xd2, 0x67, 0xa1, 0x79, 0xb2, 0x3b, 0x5b, 0xfe,
+ 0x93, 0x19, 0xc6, 0xbb, 0xb4, 0xd1, 0x1c, 0x5f, 0xf2, 0x31, 0x9c, 0x6b,
+ 0xbb, 0x4d, 0x15, 0xad, 0x98, 0x74, 0x44, 0xf9, 0x16, 0xff, 0xf3, 0x0b,
+ 0x79, 0x31, 0x9c, 0x6b, 0xbb, 0x4d, 0x12, 0xdd, 0xe0, 0x73, 0xf3, 0xae,
+ 0xcd, 0xce, 0xbf, 0xc1, 0xc5, 0xae, 0x13, 0x47, 0x5e, 0xd8, 0x09, 0x1d,
+ 0x4d, 0x44, 0x16, 0xe3, 0xa8, 0x2d, 0xb0, 0xc6, 0xf7, 0x43, 0x23, 0xaf,
+ 0xfb, 0x37, 0x1c, 0xff, 0xf7, 0x91, 0xd7, 0x2d, 0xa7, 0x54, 0x1e, 0x7c,
+ 0x8e, 0x6f, 0x86, 0x37, 0x91, 0xd7, 0xff, 0xe7, 0xdf, 0xf0, 0xf5, 0xe5,
+ 0x9a, 0x10, 0x3f, 0xd3, 0xa9, 0xa7, 0xf1, 0xd2, 0x1b, 0xf9, 0x38, 0x29,
+ 0xed, 0x1d, 0x7e, 0xe3, 0x8e, 0x41, 0xd4, 0x68, 0x86, 0xfa, 0x79, 0xee,
+ 0x57, 0x74, 0x09, 0xd7, 0xf2, 0x08, 0x71, 0x02, 0x75, 0x41, 0xbe, 0x90,
+ 0xa5, 0xf6, 0x4d, 0x2c, 0x3a, 0xff, 0xcf, 0x26, 0x33, 0x8d, 0x77, 0x69,
+ 0xa2, 0x60, 0xbf, 0x7f, 0xa7, 0x1f, 0xce, 0xbf, 0xc0, 0xdf, 0x89, 0x0b,
+ 0xc3, 0xaf, 0xfa, 0x27, 0xf0, 0xc0, 0x3d, 0xa3, 0xad, 0xee, 0x9f, 0x56,
+ 0xd9, 0x95, 0xf6, 0xed, 0x45, 0x0e, 0xac, 0x3c, 0xef, 0x15, 0xdf, 0xed,
+ 0x27, 0x51, 0x78, 0xa1, 0xd7, 0xff, 0x9e, 0x7e, 0xa4, 0x0e, 0x4c, 0x9c,
+ 0x43, 0xab, 0xc7, 0xf2, 0xc9, 0x95, 0xcd, 0xc3, 0xae, 0x07, 0xe5, 0x52,
+ 0x1a, 0xce, 0x0a, 0xdf, 0xec, 0x08, 0xe7, 0xbb, 0x87, 0x5f, 0xd3, 0xfd,
+ 0xdb, 0x71, 0xfc, 0xeb, 0xfb, 0x3d, 0xe8, 0xe6, 0x8e, 0xbf, 0x9c, 0x7f,
+ 0x9f, 0xff, 0x1d, 0x50, 0x88, 0xe1, 0x33, 0xdb, 0x2c, 0xb3, 0x10, 0xbb,
+ 0x13, 0x39, 0xf8, 0x5a, 0xf2, 0x13, 0x2d, 0x71, 0xdd, 0xcb, 0x84, 0x0b,
+ 0x21, 0x74, 0xa1, 0x87, 0x06, 0xa1, 0x35, 0xe4, 0xfd, 0x84, 0x1f, 0x61,
+ 0x7d, 0x79, 0x60, 0xe1, 0x57, 0xfe, 0x79, 0x31, 0x9c, 0x6b, 0xbb, 0x4d,
+ 0x13, 0x1d, 0xf4, 0x72, 0x36, 0x8e, 0xb3, 0x08, 0x88, 0x95, 0x8e, 0x75,
+ 0x2a, 0xfa, 0x27, 0x8e, 0x1d, 0x7e, 0xc8, 0x99, 0x16, 0x75, 0x21, 0xe3,
+ 0xf0, 0x86, 0xff, 0x76, 0x39, 0x3f, 0xd0, 0x7e, 0x75, 0xcf, 0xa3, 0xaf,
+ 0xbe, 0x7b, 0x3a, 0x75, 0xa3, 0xa6, 0xe3, 0x42, 0xb7, 0xa0, 0x67, 0x3a,
+ 0xff, 0xff, 0xfa, 0x5a, 0xee, 0x01, 0x9d, 0x77, 0x1b, 0x9a, 0xf9, 0x9b,
+ 0xcb, 0x48, 0x28, 0x75, 0xe7, 0x76, 0x9a, 0x2b, 0x1b, 0xe7, 0xfb, 0x0a,
+ 0x1d, 0x4d, 0x3c, 0xae, 0x13, 0xdf, 0xfb, 0x6f, 0x3c, 0x38, 0x08, 0x1f,
+ 0x1d, 0x4a, 0x26, 0xd4, 0xd2, 0x6d, 0xc6, 0xf9, 0x0c, 0x9f, 0x11, 0x5f,
+ 0xfc, 0x3e, 0x50, 0x10, 0x38, 0xd8, 0xe1, 0xd7, 0xfb, 0x93, 0xfb, 0x4f,
+ 0xbb, 0x4e, 0xa8, 0x3f, 0x77, 0x42, 0xbf, 0xa3, 0x6b, 0xd9, 0xbc, 0xc7,
+ 0x5f, 0xc0, 0xdb, 0x6f, 0x51, 0x52, 0x75, 0xfd, 0x9a, 0xde, 0x51, 0xd3,
+ 0xae, 0x8d, 0x87, 0x58, 0x3d, 0x3c, 0x41, 0x2d, 0xbf, 0xe8, 0xde, 0x53,
+ 0x49, 0xf9, 0x39, 0xd5, 0x08, 0xda, 0xc7, 0x84, 0x27, 0xbd, 0x12, 0xf1,
+ 0xd7, 0xfe, 0xc0, 0xf1, 0x01, 0x3f, 0xfa, 0x91, 0xd7, 0xcb, 0x7d, 0xfc,
+ 0x75, 0xff, 0xd3, 0xc7, 0xbe, 0x7d, 0x6f, 0xdd, 0xaf, 0xba, 0x3a, 0xff,
+ 0xb9, 0x1a, 0x7e, 0x0c, 0x48, 0xea, 0xe2, 0x21, 0xf6, 0x28, 0xde, 0x93,
+ 0xce, 0x75, 0xef, 0x93, 0xac, 0xeb, 0x83, 0xe3, 0xa9, 0x54, 0x98, 0xfe,
+ 0x42, 0xa7, 0x72, 0x54, 0x1c, 0x11, 0xfb, 0xff, 0x0b, 0x87, 0xb1, 0xb3,
+ 0xae, 0x27, 0x5f, 0xff, 0xf8, 0x13, 0xe3, 0x7e, 0x08, 0x36, 0xbe, 0x66,
+ 0xf2, 0xc0, 0x0f, 0xfa, 0x3a, 0xff, 0x9f, 0x71, 0xc0, 0xf5, 0xd9, 0x3a,
+ 0x82, 0x8e, 0xa1, 0x3d, 0xd3, 0xad, 0xfd, 0x3c, 0xd2, 0x55, 0x72, 0x73,
+ 0xaf, 0x84, 0x73, 0xc7, 0x52, 0xb2, 0x7a, 0x90, 0x6b, 0x7f, 0x4f, 0xf7,
+ 0x6d, 0xc7, 0xf3, 0xaf, 0xfe, 0x9b, 0xae, 0xbf, 0x76, 0x3c, 0x05, 0x9d,
+ 0x7f, 0xc9, 0x24, 0xe8, 0x16, 0xb4, 0x3a, 0xa1, 0x15, 0xf8, 0x67, 0xe4,
+ 0x5b, 0xdd, 0x46, 0x21, 0x90, 0xaf, 0x22, 0x1c, 0x8f, 0x65, 0xb0, 0xc9,
+ 0xe1, 0x07, 0x63, 0x0b, 0x72, 0xd1, 0x1b, 0xd4, 0x6b, 0xfe, 0x8c, 0xf3,
+ 0x6e, 0x10, 0x7f, 0x61, 0xab, 0x74, 0x84, 0xeb, 0xfb, 0x9c, 0x80, 0xe2,
+ 0xce, 0xbb, 0xef, 0xe7, 0x5e, 0xea, 0x2c, 0xeb, 0x4c, 0x75, 0x39, 0xac,
+ 0x00, 0xdd, 0xf9, 0xc6, 0x70, 0x68, 0xeb, 0xfe, 0x80, 0xf7, 0x03, 0xc7,
+ 0x69, 0xd4, 0x88, 0xef, 0xfc, 0xb0, 0x51, 0x74, 0x41, 0xe2, 0x7b, 0xda,
+ 0xfb, 0xa3, 0xaf, 0xb7, 0x9e, 0x14, 0x3a, 0x82, 0x78, 0x40, 0x1e, 0xbb,
+ 0xd0, 0x75, 0xf9, 0x78, 0x31, 0x23, 0xaf, 0x81, 0xec, 0xd1, 0xd7, 0xd1,
+ 0xc7, 0x13, 0xaf, 0xf3, 0xf2, 0x5f, 0xa6, 0xfa, 0x3a, 0xfb, 0x5a, 0x8f,
+ 0xce, 0xa8, 0x45, 0xda, 0x12, 0xf4, 0x84, 0x03, 0xec, 0x9a, 0x5f, 0x4b,
+ 0xf0, 0x48, 0xeb, 0xee, 0x7d, 0x8f, 0xce, 0xa8, 0x3c, 0x74, 0x23, 0xbf,
+ 0xc9, 0x3b, 0xaf, 0xff, 0xe0, 0xeb, 0xfe, 0x46, 0xf7, 0x26, 0x18, 0x09,
+ 0xd7, 0xd2, 0xf6, 0x7d, 0x3a, 0xf3, 0x63, 0xf3, 0xaf, 0x72, 0x16, 0x75,
+ 0x39, 0xed, 0x00, 0x8d, 0x91, 0xcb, 0xf4, 0x4f, 0xf7, 0x26, 0x3a, 0xf4,
+ 0x0c, 0x8e, 0xa9, 0x93, 0x58, 0xe1, 0x07, 0x4d, 0x06, 0x12, 0x3a, 0x2f,
+ 0xf1, 0x55, 0xff, 0xa3, 0x35, 0xf2, 0x10, 0x3f, 0x64, 0x75, 0xfc, 0x8c,
+ 0xea, 0x7c, 0x64, 0xea, 0x13, 0xef, 0xf2, 0x05, 0xfa, 0x03, 0xec, 0x69,
+ 0xd7, 0xdd, 0x81, 0x69, 0xd5, 0x23, 0xe7, 0xd1, 0x0f, 0x89, 0xaf, 0x9c,
+ 0x5e, 0x63, 0xaf, 0xc9, 0xe1, 0xc9, 0x1d, 0x7d, 0x0c, 0xc4, 0xc7, 0x5d,
+ 0xf5, 0x67, 0x5f, 0xf0, 0x3e, 0x78, 0x5f, 0xfc, 0x13, 0xaa, 0x74, 0x5c,
+ 0x28, 0x40, 0x84, 0xbd, 0x22, 0x11, 0x8b, 0xfd, 0x0c, 0x84, 0x0f, 0xc9,
+ 0x1d, 0x7f, 0x27, 0x37, 0xd4, 0x48, 0xeb, 0x6c, 0x3a, 0xb8, 0x7e, 0x5d,
+ 0x33, 0xda, 0x2d, 0xbc, 0x28, 0xa1, 0xd7, 0xd8, 0x14, 0xd8, 0x75, 0xd0,
+ 0xbc, 0x37, 0xae, 0x37, 0x6d, 0x1d, 0x48, 0x6e, 0x9c, 0xaa, 0xef, 0xe0,
+ 0xab, 0x99, 0x64, 0xaa, 0x43, 0x5c, 0xc8, 0xb5, 0xfe, 0x79, 0x0e, 0x7b,
+ 0xa8, 0x53, 0x06, 0x86, 0xf3, 0xef, 0xa3, 0xaf, 0xbe, 0xf5, 0xfc, 0x75,
+ 0x04, 0xdf, 0xf8, 0x72, 0xf4, 0x0c, 0xc7, 0x5c, 0x30, 0x75, 0xa6, 0x3a,
+ 0xa6, 0x3c, 0x0e, 0x0d, 0xb8, 0xa5, 0xff, 0xca, 0x20, 0xb7, 0x50, 0xb7,
+ 0xdf, 0xc7, 0x5e, 0xff, 0x36, 0x8e, 0xa5, 0x0f, 0x8f, 0x88, 0x97, 0xcb,
+ 0xd0, 0x16, 0x75, 0x94, 0x3a, 0xdb, 0x67, 0x5d, 0xc5, 0x0e, 0xa8, 0x3d,
+ 0xd4, 0x22, 0x00, 0x8f, 0xd1, 0x3b, 0xff, 0xee, 0xe4, 0xb5, 0x1e, 0x96,
+ 0x2b, 0xb8, 0xfe, 0x75, 0xff, 0xa4, 0x9e, 0xee, 0x6f, 0xe0, 0x41, 0xd7,
+ 0x66, 0x8e, 0xa8, 0x3d, 0x39, 0x1f, 0x56, 0x91, 0x8b, 0xe8, 0x52, 0x5f,
+ 0x92, 0x17, 0x0b, 0x3a, 0xd8, 0x75, 0x21, 0xee, 0x68, 0xa3, 0x6c, 0x96,
+ 0xa1, 0x58, 0x0e, 0x30, 0xa4, 0x24, 0xbb, 0x08, 0x07, 0x8d, 0x76, 0xf6,
+ 0xa2, 0x63, 0xa8, 0xeb, 0x2c, 0xea, 0xf1, 0x75, 0xb0, 0x2a, 0xfd, 0xfa,
+ 0x71, 0x14, 0x3a, 0xe7, 0x50, 0xea, 0x99, 0x12, 0xdd, 0x36, 0xfc, 0x88,
+ 0x4a, 0x2e, 0xf4, 0x1d, 0x7e, 0x8e, 0xe6, 0xc7, 0x3a, 0x9c, 0xde, 0x7e,
+ 0x2b, 0x7f, 0x27, 0xb3, 0xae, 0xa1, 0xd7, 0xf7, 0x40, 0xf3, 0xf5, 0x0e,
+ 0xbc, 0xcb, 0x2c, 0x95, 0x7f, 0xc1, 0x89, 0xfe, 0xe7, 0x5f, 0x72, 0x98,
+ 0x2f, 0xee, 0xc9, 0xce, 0xa0, 0xa2, 0xb5, 0xa9, 0x88, 0x97, 0x7a, 0x16,
+ 0x87, 0x56, 0x1e, 0x4b, 0x4b, 0xef, 0x93, 0x9b, 0x41, 0x3a, 0xfd, 0xd8,
+ 0xdd, 0xd5, 0xce, 0xbf, 0xfe, 0x8f, 0x68, 0x39, 0xe4, 0xe8, 0x33, 0x7f,
+ 0x1d, 0x5d, 0x3f, 0x9f, 0x15, 0x5b, 0x87, 0x5f, 0xec, 0xc6, 0xfd, 0xd9,
+ 0xdc, 0x3a, 0xe0, 0x68, 0xeb, 0xff, 0xf6, 0x06, 0x33, 0x7f, 0xbe, 0x41,
+ 0x04, 0xb3, 0x47, 0x5c, 0xbf, 0xce, 0xb9, 0xc4, 0xea, 0xe9, 0xab, 0x71,
+ 0x7b, 0xf2, 0xd3, 0xdf, 0xb9, 0xd5, 0x3a, 0x7c, 0x39, 0x09, 0xd5, 0x72,
+ 0x29, 0x84, 0x1c, 0xd4, 0x45, 0xbd, 0x08, 0x00, 0x10, 0x5f, 0x77, 0xc9,
+ 0x39, 0xd7, 0xf9, 0xa9, 0xa1, 0xcd, 0x8e, 0x75, 0xf4, 0x4e, 0xf2, 0x3a,
+ 0xec, 0xf1, 0xd7, 0xec, 0x9c, 0x73, 0x73, 0xab, 0x11, 0x63, 0xb9, 0x17,
+ 0x0c, 0xba, 0x42, 0x22, 0xb7, 0xbb, 0x01, 0x3a, 0xee, 0x68, 0xea, 0x39,
+ 0x0b, 0x6b, 0xfd, 0x03, 0x27, 0x5e, 0x04, 0xeb, 0xef, 0x2d, 0x7c, 0x3a,
+ 0xff, 0xef, 0xe0, 0x5a, 0xfe, 0xff, 0xe8, 0xc8, 0xeb, 0xd2, 0x4e, 0x9d,
+ 0x7d, 0xe1, 0xc9, 0x1d, 0x7e, 0xc0, 0x2a, 0x74, 0xe7, 0x5f, 0xfe, 0x4d,
+ 0x77, 0x02, 0x39, 0xb0, 0x73, 0x47, 0x54, 0x93, 0x45, 0x50, 0xc3, 0x72,
+ 0x29, 0x91, 0xb8, 0x36, 0x24, 0x1e, 0x2a, 0xa5, 0x53, 0x67, 0xe3, 0x11,
+ 0x82, 0x4f, 0x08, 0xb9, 0x11, 0x06, 0x1a, 0x19, 0x1f, 0x46, 0xf1, 0x99,
+ 0xa4, 0x39, 0xe6, 0x85, 0xe7, 0x21, 0x52, 0xb6, 0xee, 0xcb, 0x81, 0x78,
+ 0x77, 0x7e, 0xf4, 0xa9, 0x21, 0x18, 0xc8, 0xb5, 0x28, 0x0b, 0xd1, 0x97,
+ 0xb2, 0x93, 0xb6, 0x63, 0xf6, 0x35, 0xdb, 0xfe, 0x63, 0xc9, 0x9b, 0x5a,
+ 0x04, 0x1d, 0x7f, 0xff, 0xc0, 0x86, 0x3d, 0xa4, 0xeb, 0xa7, 0xb3, 0x9f,
+ 0xad, 0xe4, 0x75, 0x30, 0xa8, 0x76, 0x78, 0xdf, 0x02, 0x77, 0x7e, 0xe3,
+ 0x5d, 0xda, 0x68, 0xad, 0xef, 0xfc, 0xf2, 0x63, 0x38, 0xd7, 0x76, 0x9a,
+ 0x27, 0x0b, 0x31, 0x87, 0xfa, 0xb3, 0x3b, 0x95, 0x41, 0x3a, 0xdd, 0x3a,
+ 0xda, 0x3a, 0x80, 0x68, 0x36, 0xc4, 0x2f, 0x9a, 0xee, 0xd3, 0x45, 0xa3,
+ 0x7f, 0xfb, 0x03, 0xd7, 0x52, 0x69, 0x93, 0x40, 0x59, 0xd5, 0xc3, 0xf9,
+ 0xe9, 0x6d, 0xf3, 0x5c, 0x7f, 0x3a, 0xff, 0xa6, 0xc5, 0x7d, 0x73, 0x8f,
+ 0xe3, 0xaf, 0xe8, 0x71, 0x00, 0x70, 0xeb, 0x91, 0x43, 0xaf, 0xff, 0xd3,
+ 0xc7, 0xa0, 0x3c, 0x8e, 0xbe, 0x87, 0x3f, 0x3a, 0xff, 0xd1, 0xbb, 0xab,
+ 0xf4, 0x5d, 0x5e, 0x73, 0xaf, 0xfd, 0x1c, 0xff, 0x13, 0x39, 0xe0, 0x1d,
+ 0x50, 0x8d, 0x5e, 0xaa, 0x69, 0x12, 0xd9, 0x32, 0x63, 0x5a, 0x87, 0x5d,
+ 0xfe, 0xef, 0x40, 0xa2, 0xe3, 0x47, 0x5f, 0xff, 0x93, 0x43, 0x9b, 0x1f,
+ 0xc3, 0x9a, 0xeb, 0xcc, 0x75, 0x62, 0x22, 0x26, 0x34, 0xbe, 0xcf, 0xdf,
+ 0xa7, 0x5d, 0xdd, 0x1d, 0x66, 0x15, 0x0a, 0xea, 0xd5, 0xb3, 0xac, 0x84,
+ 0xeb, 0x48, 0xa6, 0x21, 0x59, 0xe7, 0x63, 0x44, 0xf4, 0x2d, 0xf6, 0xc8,
+ 0xfe, 0x90, 0xdf, 0x35, 0xdd, 0xa6, 0x8b, 0x6a, 0xff, 0xfe, 0x87, 0xf4,
+ 0x76, 0x34, 0x89, 0x24, 0xe6, 0x04, 0xeb, 0xfb, 0xb0, 0xb8, 0x40, 0x9d,
+ 0x5c, 0x45, 0x76, 0x8b, 0x7c, 0xad, 0x7f, 0xee, 0xa0, 0x5e, 0x41, 0xea,
+ 0x2c, 0xeb, 0xe8, 0xd9, 0x88, 0x75, 0xff, 0x44, 0xa3, 0x93, 0xc7, 0x27,
+ 0x3a, 0xff, 0xa3, 0x9f, 0x35, 0x1d, 0x74, 0x3a, 0xff, 0x75, 0x1e, 0x5e,
+ 0x49, 0xce, 0xac, 0x4c, 0xc5, 0xa6, 0x1c, 0x3d, 0x12, 0x16, 0x4e, 0x76,
+ 0xce, 0x2f, 0xe5, 0x1f, 0x81, 0x00, 0x9d, 0x7f, 0x0e, 0xda, 0x73, 0x14,
+ 0x3a, 0xfc, 0x93, 0xae, 0x1a, 0x75, 0xf9, 0xf7, 0x97, 0xdd, 0x1d, 0x66,
+ 0x14, 0x45, 0x68, 0x96, 0xf8, 0xbf, 0x61, 0x3d, 0x30, 0x9a, 0x6f, 0xf1,
+ 0x83, 0xdc, 0xbe, 0x9d, 0x7e, 0xe3, 0x5d, 0xda, 0x68, 0xb9, 0x6c, 0xc0,
+ 0x4f, 0x27, 0x05, 0xaf, 0xdc, 0x6b, 0xbb, 0x4d, 0x17, 0x6d, 0xff, 0x24,
+ 0xa4, 0x83, 0xfc, 0x48, 0xeb, 0x31, 0x87, 0xd4, 0xe6, 0x75, 0x0e, 0xc5,
+ 0x3a, 0x72, 0x99, 0x4f, 0x31, 0x06, 0x36, 0x85, 0x29, 0x1a, 0x89, 0x5b,
+ 0x78, 0xab, 0xc2, 0xdf, 0xb2, 0xf4, 0xc6, 0x5e, 0xf6, 0x9d, 0x7d, 0x09,
+ 0x2b, 0xfc, 0xc6, 0x71, 0xae, 0xed, 0x34, 0x54, 0xf7, 0x83, 0x3a, 0xce,
+ 0xb7, 0x8e, 0xbf, 0xe8, 0x79, 0xfe, 0x6f, 0xa8, 0x09, 0xd4, 0x87, 0x96,
+ 0x22, 0x17, 0xcd, 0x77, 0x69, 0xa2, 0xb9, 0xbf, 0xcc, 0x67, 0x1a, 0xee,
+ 0xd3, 0x45, 0x9d, 0x79, 0xde, 0x47, 0x5f, 0xc9, 0xac, 0x17, 0x64, 0xea,
+ 0xe2, 0x2c, 0x7a, 0x5a, 0x27, 0xfe, 0x1a, 0xbf, 0xfd, 0xe8, 0xd7, 0xc0,
+ 0x6b, 0xd1, 0x34, 0xc8, 0x75, 0xfc, 0x8b, 0x9c, 0x1c, 0x91, 0xd7, 0xfa,
+ 0x3b, 0xf1, 0x6a, 0xda, 0xa3, 0xc7, 0x56, 0x22, 0xe7, 0xa9, 0xbb, 0x0b,
+ 0xaf, 0xdc, 0xcf, 0x22, 0xce, 0xbe, 0x71, 0x80, 0x9d, 0x7f, 0x64, 0xd0,
+ 0xb8, 0xfa, 0x75, 0xfb, 0x8d, 0x77, 0x69, 0xa2, 0x42, 0xbf, 0xf6, 0x2f,
+ 0x1f, 0x93, 0xfc, 0xdd, 0x67, 0x5f, 0xf2, 0x6f, 0xaf, 0x0c, 0x2f, 0x47,
+ 0x5d, 0x26, 0x31, 0x15, 0x9d, 0x33, 0xfd, 0x06, 0xff, 0xee, 0xa2, 0xf3,
+ 0x5f, 0x37, 0x96, 0x78, 0xeb, 0xe9, 0x77, 0xee, 0x8e, 0xa8, 0x3e, 0xac,
+ 0x46, 0xbe, 0x56, 0xfb, 0x0b, 0x3a, 0xfe, 0xee, 0xb5, 0x9c, 0x9c, 0xeb,
+ 0xa1, 0x93, 0xab, 0x0f, 0x11, 0x0b, 0xac, 0xc4, 0xeb, 0x99, 0xe1, 0x68,
+ 0xc8, 0x68, 0xa4, 0x3d, 0x78, 0x62, 0xb2, 0x6e, 0x8f, 0xbc, 0x36, 0x86,
+ 0x14, 0xfa, 0x20, 0xf3, 0x55, 0xff, 0xcc, 0x75, 0xf4, 0x39, 0xef, 0x47,
+ 0xe7, 0x5f, 0xfe, 0x61, 0x6f, 0x26, 0x33, 0x8d, 0x77, 0x69, 0xa2, 0x7c,
+ 0xa6, 0xaf, 0x2e, 0x2b, 0xce, 0x87, 0x2e, 0x16, 0x7d, 0x44, 0xb9, 0x37,
+ 0x3a, 0xff, 0xfa, 0x53, 0xaa, 0xd0, 0xad, 0xce, 0xde, 0x7c, 0xf9, 0xdd,
+ 0xb3, 0xaa, 0x47, 0xf5, 0xf8, 0xb5, 0xfb, 0x39, 0x99, 0x31, 0xd6, 0x63,
+ 0xa7, 0x93, 0xf4, 0x8e, 0xfd, 0xc6, 0xbb, 0xb4, 0xd1, 0x59, 0x5f, 0xf9,
+ 0xe4, 0xc6, 0x71, 0xae, 0xed, 0x34, 0x4d, 0xd6, 0x63, 0x0f, 0xf5, 0x66,
+ 0x74, 0xd4, 0x68, 0x24, 0x2a, 0x2f, 0xdc, 0x6b, 0xbb, 0x4d, 0x12, 0xb5,
+ 0xf8, 0x60, 0x2f, 0xd3, 0xaf, 0xcc, 0x2d, 0xe4, 0xc6, 0x1e, 0xc2, 0x19,
+ 0xdf, 0xfb, 0xd8, 0xc6, 0x71, 0x27, 0x75, 0x9d, 0x7f, 0xf9, 0x58, 0x56,
+ 0x55, 0x1a, 0xc7, 0x92, 0x67, 0x30, 0xeb, 0xff, 0x26, 0x80, 0xb1, 0x4d,
+ 0x80, 0x73, 0xaf, 0xe8, 0x17, 0x6b, 0xab, 0x9d, 0x52, 0x3e, 0xb5, 0x9f,
+ 0x5c, 0x1e, 0x1d, 0x7e, 0xe3, 0x5d, 0xda, 0x68, 0x97, 0x2f, 0xf9, 0x1e,
+ 0x5e, 0x18, 0x5e, 0x8e, 0xbf, 0x4b, 0x6d, 0x3a, 0xe7, 0x5e, 0x8d, 0xb8,
+ 0x3a, 0xf2, 0x0c, 0x1d, 0x52, 0x3d, 0xf0, 0x94, 0xec, 0x1d, 0xbf, 0xff,
+ 0x3f, 0x90, 0x12, 0x14, 0x94, 0x78, 0x41, 0x23, 0xaf, 0xe9, 0x77, 0x07,
+ 0x1a, 0x75, 0xe9, 0x77, 0xc7, 0x5d, 0xd8, 0x43, 0xc7, 0xe9, 0x5d, 0xff,
+ 0xc2, 0x9f, 0xeb, 0x90, 0x92, 0x7d, 0x1d, 0x58, 0x7d, 0xc8, 0x59, 0x79,
+ 0xe4, 0xc2, 0xaf, 0x56, 0x31, 0x10, 0xc0, 0x91, 0x16, 0x0b, 0x74, 0xcd,
+ 0xe1, 0x2b, 0xa3, 0x1f, 0x46, 0x0f, 0x66, 0x11, 0x5f, 0x72, 0xe5, 0xab,
+ 0x5f, 0xfc, 0xc3, 0xc9, 0x8c, 0xe3, 0x5d, 0xda, 0x68, 0x8e, 0xef, 0xfb,
+ 0xdd, 0xc9, 0x30, 0xe3, 0xa3, 0xaf, 0xe5, 0x50, 0xc3, 0x70, 0x4e, 0xb8,
+ 0x1d, 0x3a, 0xfe, 0x54, 0x0e, 0x75, 0xfc, 0x75, 0xff, 0xfd, 0xe9, 0x20,
+ 0x7a, 0x9b, 0x3e, 0x60, 0x78, 0x80, 0x69, 0xd7, 0xfb, 0x19, 0xd4, 0x0f,
+ 0xb4, 0x75, 0xfe, 0x71, 0xfd, 0xf8, 0xff, 0x4e, 0xbf, 0xf2, 0x73, 0xe6,
+ 0x87, 0x17, 0x0d, 0x3a, 0xff, 0xd0, 0x20, 0xf2, 0x3e, 0xc7, 0x91, 0xd7,
+ 0xcd, 0x77, 0x69, 0xa2, 0xa1, 0xbf, 0xec, 0xee, 0x0b, 0xf3, 0x88, 0x75,
+ 0x28, 0x8d, 0xd6, 0x9f, 0x70, 0xf7, 0x45, 0xb7, 0x4b, 0x0e, 0xbf, 0xe9,
+ 0x79, 0x38, 0xed, 0x41, 0x3a, 0xff, 0xf3, 0xaf, 0x38, 0x38, 0x9b, 0x13,
+ 0x8e, 0x75, 0xff, 0xdd, 0x1c, 0x9b, 0xdd, 0xce, 0x26, 0x8e, 0xbf, 0x6e,
+ 0x28, 0xb4, 0x3a, 0xa1, 0x16, 0x18, 0x8e, 0x88, 0x77, 0xfa, 0x3c, 0xfd,
+ 0xf8, 0x18, 0x3a, 0xff, 0xc0, 0xf8, 0xe3, 0x9b, 0x5f, 0x3a, 0x03, 0xaf,
+ 0xf4, 0xa3, 0x93, 0xc7, 0x27, 0x3a, 0xff, 0xed, 0x6b, 0x07, 0xda, 0xc9,
+ 0x27, 0x4e, 0xbf, 0xfe, 0x8f, 0xf0, 0x7e, 0x3f, 0xbe, 0x77, 0x3f, 0x73,
+ 0xae, 0x19, 0xce, 0xa8, 0x46, 0xf6, 0x1a, 0x22, 0x10, 0xa9, 0x5f, 0xdb,
+ 0x1d, 0x7d, 0x65, 0xce, 0xbf, 0xff, 0xc9, 0x1e, 0x7e, 0xb1, 0xae, 0xe0,
+ 0xfb, 0xe7, 0xf2, 0xd1, 0xd6, 0xc4, 0x44, 0x90, 0x97, 0xdf, 0x77, 0xd9,
+ 0x39, 0xd7, 0xec, 0x9d, 0xc7, 0x61, 0xd7, 0xff, 0xff, 0xfa, 0x25, 0xf3,
+ 0xdd, 0x48, 0xd7, 0xcc, 0x03, 0x63, 0x67, 0xcc, 0xe7, 0x33, 0x60, 0x1f,
+ 0xa7, 0x5f, 0x74, 0x5f, 0x68, 0xea, 0xc4, 0xc0, 0xc4, 0x8b, 0x45, 0x1e,
+ 0x84, 0xb5, 0xff, 0xff, 0x01, 0xd5, 0xd2, 0x7e, 0xba, 0x7a, 0x3a, 0x9e,
+ 0xd6, 0x04, 0xeb, 0x30, 0xa8, 0x5f, 0x6a, 0x56, 0xcb, 0x95, 0x42, 0xd0,
+ 0x5f, 0x3a, 0xf0, 0x4c, 0xb2, 0x31, 0x06, 0x9f, 0x6e, 0x2b, 0xc8, 0x73,
+ 0x2c, 0xb7, 0xa6, 0x63, 0x19, 0x16, 0xa1, 0x97, 0xe8, 0xca, 0x76, 0xd0,
+ 0x6f, 0x9a, 0xee, 0xd3, 0x45, 0x51, 0x7f, 0xb9, 0x1b, 0x37, 0x96, 0x78,
+ 0xea, 0xe1, 0xf1, 0x00, 0xb6, 0xff, 0xcf, 0x26, 0x33, 0x8d, 0x77, 0x69,
+ 0xa2, 0x6b, 0xbc, 0xb7, 0xf1, 0xd6, 0x63, 0x11, 0x0e, 0xb2, 0x27, 0x4a,
+ 0xbf, 0x71, 0xae, 0xed, 0x34, 0x55, 0x97, 0xfd, 0x12, 0x8e, 0x4f, 0x1c,
+ 0x9c, 0xeb, 0x31, 0x87, 0xd8, 0x26, 0x77, 0xfe, 0x63, 0xb1, 0xbf, 0xa3,
+ 0xae, 0xae, 0x75, 0xff, 0xcc, 0x3c, 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x89,
+ 0x12, 0xfd, 0xc6, 0xbb, 0xb4, 0xd1, 0x69, 0x5f, 0xf9, 0xe4, 0xc6, 0x71,
+ 0xae, 0xed, 0x34, 0x4f, 0xb6, 0x63, 0x0f, 0xf5, 0x66, 0x77, 0xff, 0x98,
+ 0x5b, 0xc9, 0x8c, 0xe3, 0x5d, 0xda, 0x68, 0xa1, 0x2f, 0xdd, 0x49, 0xe3,
+ 0x87, 0x5f, 0xb8, 0xd7, 0x76, 0x9a, 0x28, 0xfb, 0xfe, 0x89, 0x47, 0x27,
+ 0x8e, 0x4e, 0x75, 0xff, 0x86, 0x26, 0x81, 0x89, 0xbb, 0x07, 0x5f, 0xff,
+ 0xd8, 0x1e, 0xc7, 0xd6, 0x3c, 0x2f, 0xfe, 0xb5, 0x1f, 0x95, 0x7e, 0x61,
+ 0x6f, 0x26, 0x21, 0x32, 0xdc, 0x27, 0x13, 0x3f, 0x1c, 0xed, 0x9e, 0x54,
+ 0x36, 0x46, 0xf3, 0xce, 0x16, 0xc8, 0xcb, 0x14, 0x54, 0x9f, 0xa2, 0x6c,
+ 0x7e, 0xfb, 0xc2, 0x85, 0x09, 0xe6, 0x42, 0xec, 0x33, 0xbf, 0x28, 0xf4,
+ 0x70, 0x97, 0xf9, 0x8c, 0xe3, 0x5d, 0xda, 0x68, 0x88, 0xaf, 0xec, 0xe3,
+ 0x5d, 0xda, 0x68, 0x8a, 0xef, 0xf9, 0x5d, 0x8c, 0xe3, 0x5d, 0xda, 0x68,
+ 0xae, 0x29, 0x84, 0x40, 0x39, 0xc5, 0xff, 0xef, 0xe0, 0x5a, 0xc3, 0xfb,
+ 0xff, 0xa3, 0x23, 0xaf, 0x98, 0x9e, 0x65, 0x73, 0xac, 0x9b, 0x9f, 0xaf,
+ 0xe9, 0xb7, 0xd9, 0xd7, 0xf1, 0xd7, 0xfb, 0x13, 0x9f, 0xfe, 0x0d, 0x1d,
+ 0x65, 0x40, 0x9e, 0xa6, 0x88, 0x2f, 0xff, 0xef, 0x69, 0x3a, 0xe9, 0x24,
+ 0x1f, 0x03, 0xbc, 0xc3, 0xaf, 0xdc, 0x6b, 0xbb, 0x4d, 0x14, 0xf5, 0xfe,
+ 0x5a, 0x04, 0x0f, 0xc9, 0x1d, 0x72, 0xd0, 0xea, 0x83, 0xc7, 0x69, 0x95,
+ 0xff, 0xfe, 0x94, 0x7b, 0x40, 0x5b, 0x53, 0xf8, 0xce, 0xa0, 0x1a, 0x75,
+ 0xff, 0xfd, 0xce, 0x03, 0x9c, 0x81, 0xc5, 0x13, 0xbd, 0xcf, 0xa7, 0x5f,
+ 0xfc, 0x92, 0xc1, 0xfe, 0x16, 0x9c, 0x91, 0xd7, 0xfa, 0x51, 0xc9, 0xe3,
+ 0x93, 0x9d, 0x7d, 0xf0, 0x5e, 0x47, 0x5f, 0x9f, 0x3a, 0x8b, 0x3a, 0xb4,
+ 0x78, 0xfb, 0x08, 0xaa, 0x11, 0x3f, 0x8f, 0x77, 0xfd, 0x02, 0xdc, 0xd9,
+ 0x9e, 0xd1, 0xd7, 0xe7, 0x9e, 0x38, 0x03, 0xa9, 0x54, 0xac, 0xee, 0x0a,
+ 0xf1, 0x61, 0xaf, 0x5b, 0x90, 0xa3, 0x03, 0xae, 0x0c, 0x38, 0x76, 0x10,
+ 0xed, 0x9c, 0x5f, 0xfe, 0x79, 0x30, 0x11, 0x76, 0x75, 0xa8, 0xfc, 0xeb,
+ 0xff, 0xdf, 0xfe, 0x0d, 0x31, 0xf4, 0x5d, 0x63, 0x07, 0x5f, 0xfc, 0x39,
+ 0xfb, 0x8f, 0xec, 0x2d, 0x16, 0x75, 0x71, 0x12, 0x3e, 0x4d, 0xa6, 0x13,
+ 0x96, 0x0c, 0x25, 0xd2, 0x1b, 0x97, 0x07, 0x0e, 0xbf, 0xf9, 0x03, 0xc7,
+ 0xdd, 0x8e, 0x72, 0x27, 0x3a, 0x98, 0x3d, 0xbe, 0x8a, 0xdc, 0x18, 0x3a,
+ 0xff, 0xfd, 0xd8, 0xe6, 0x49, 0x1f, 0xd8, 0x14, 0x03, 0x4a, 0xbf, 0x44,
+ 0xbf, 0x04, 0x8e, 0xbe, 0x6b, 0xbb, 0x4d, 0x15, 0x9d, 0x4c, 0x7a, 0xbc,
+ 0x28, 0xbe, 0xf2, 0x2f, 0x47, 0x5f, 0xd3, 0xae, 0x06, 0x5a, 0x3a, 0xfd,
+ 0x9e, 0xd7, 0xdd, 0x1d, 0x7a, 0x27, 0x43, 0xaf, 0xde, 0xff, 0xe8, 0xc8,
+ 0xeb, 0xc0, 0x7d, 0x1d, 0x7f, 0xd9, 0x24, 0x02, 0xba, 0xb7, 0xfa, 0xce,
+ 0xbf, 0x64, 0xd3, 0x83, 0xf3, 0xac, 0xc4, 0x2a, 0x21, 0x08, 0xae, 0x42,
+ 0x9f, 0x72, 0x3e, 0x10, 0xac, 0xb7, 0xa5, 0x2e, 0x36, 0x25, 0x5a, 0x1b,
+ 0xfa, 0x83, 0x7f, 0xee, 0xa7, 0x9f, 0x93, 0xc2, 0x04, 0xeb, 0xf7, 0x90,
+ 0x71, 0x67, 0x5f, 0x49, 0xc5, 0x8c, 0x3e, 0x2d, 0xa3, 0xdb, 0xff, 0x3c,
+ 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x89, 0x16, 0xff, 0xcf, 0xe6, 0x21, 0x38,
+ 0x9e, 0x01, 0xd4, 0xc2, 0x21, 0xdd, 0x2a, 0xfe, 0xce, 0x35, 0xdd, 0xa6,
+ 0x8b, 0x26, 0xff, 0xf7, 0xb5, 0xf7, 0x4c, 0x64, 0xe8, 0x32, 0xd1, 0xd4,
+ 0xc2, 0x21, 0x70, 0xe2, 0xff, 0xff, 0x3a, 0x78, 0x1c, 0x7d, 0x30, 0xde,
+ 0xa7, 0x22, 0x5a, 0x3a, 0xfe, 0xce, 0x35, 0xdd, 0xa6, 0x8b, 0x62, 0xff,
+ 0xfe, 0x54, 0x77, 0xe0, 0xe7, 0x3d, 0xae, 0xcd, 0xf3, 0xe7, 0x76, 0xce,
+ 0xbd, 0xc0, 0x74, 0xeb, 0xbc, 0xc4, 0x22, 0x1b, 0x8d, 0x54, 0xc2, 0x3b,
+ 0x52, 0x17, 0xd7, 0xb3, 0x58, 0x75, 0xf3, 0x5d, 0xda, 0x68, 0xb6, 0xef,
+ 0xb5, 0x3b, 0xf0, 0xea, 0xe1, 0xe7, 0xf8, 0xb6, 0xfe, 0x4e, 0xf9, 0x3f,
+ 0x01, 0xd7, 0xfd, 0x12, 0x8e, 0x4f, 0x1c, 0x9c, 0xeb, 0x31, 0x24, 0x78,
+ 0xe3, 0x4c, 0xc4, 0x42, 0x5b, 0x7f, 0xfb, 0x07, 0xf6, 0x16, 0xe1, 0xcc,
+ 0x15, 0x0e, 0xbc, 0xaa, 0xe8, 0x4e, 0xbd, 0x3f, 0x50, 0xeb, 0xff, 0x2a,
+ 0x95, 0x4a, 0xd3, 0xdd, 0xc1, 0x8f, 0xce, 0xbf, 0xa0, 0x64, 0x10, 0x2c,
+ 0xeb, 0xe6, 0xbb, 0xb4, 0xd1, 0x78, 0x5f, 0xf9, 0xfd, 0x1b, 0x39, 0xcc,
+ 0xdf, 0x47, 0x57, 0x0f, 0xb4, 0x4b, 0x6f, 0xbd, 0xb7, 0x9d, 0x3a, 0xfc,
+ 0xb8, 0x19, 0x39, 0xd7, 0xfa, 0x50, 0x3e, 0xd8, 0xed, 0x3a, 0xff, 0x47,
+ 0x9f, 0xbf, 0x03, 0x07, 0x5f, 0xfb, 0xea, 0xf7, 0x97, 0xb0, 0x7d, 0xa3,
+ 0xae, 0xc5, 0x0e, 0xa8, 0x3d, 0x7c, 0x41, 0xbe, 0x49, 0xf1, 0x67, 0x5f,
+ 0xb0, 0x7f, 0xda, 0x83, 0xaf, 0xd1, 0xf4, 0x0f, 0xa3, 0xaf, 0xff, 0x62,
+ 0xe1, 0xbf, 0x30, 0x41, 0x2c, 0xd1, 0xd7, 0xff, 0x67, 0x7a, 0xf2, 0x5a,
+ 0x47, 0x24, 0x75, 0xd1, 0xf9, 0xd5, 0x23, 0xd8, 0xf2, 0x15, 0x2a, 0x15,
+ 0xce, 0xaa, 0x88, 0x15, 0x78, 0xe4, 0xe9, 0x99, 0x09, 0x9d, 0xc8, 0x50,
+ 0x92, 0x62, 0x55, 0x99, 0xf6, 0x11, 0x4e, 0x41, 0xf9, 0x08, 0x94, 0xe8,
+ 0xa3, 0xd0, 0xa1, 0xbf, 0xdb, 0xb1, 0x9f, 0xbf, 0x34, 0x75, 0xfe, 0xfd,
+ 0x89, 0xa5, 0x03, 0xe3, 0xa9, 0x84, 0xd5, 0x62, 0x1d, 0x7c, 0x35, 0xbc,
+ 0x99, 0xb9, 0xd7, 0xcd, 0x77, 0x69, 0xa2, 0xf4, 0xbf, 0xf2, 0x7b, 0xa2,
+ 0xf2, 0xfd, 0xff, 0x3a, 0xb8, 0x7d, 0x6b, 0x2d, 0xbc, 0xb4, 0xf1, 0xd7,
+ 0xfc, 0xfe, 0x94, 0x29, 0xe4, 0x9c, 0xea, 0x59, 0xea, 0x08, 0xdd, 0xfb,
+ 0x17, 0xd7, 0x09, 0xd4, 0x14, 0xd0, 0xf2, 0x10, 0xdf, 0x5d, 0xb6, 0x88,
+ 0x6f, 0xff, 0xf9, 0x36, 0x60, 0xb0, 0x1c, 0x0f, 0x71, 0x6b, 0x79, 0x60,
+ 0x9d, 0x4c, 0x22, 0xb3, 0x11, 0xea, 0x1b, 0x63, 0xf9, 0xe1, 0x7f, 0x28,
+ 0x4c, 0x64, 0xea, 0x73, 0x61, 0x2c, 0x92, 0x91, 0x26, 0x8c, 0x1f, 0x90,
+ 0xc2, 0x5c, 0x2a, 0x3a, 0x47, 0xfc, 0x69, 0xa3, 0x18, 0xce, 0x90, 0xc1,
+ 0x3a, 0x76, 0xcc, 0xa2, 0x5b, 0x81, 0xd3, 0xaf, 0xfe, 0x04, 0x4c, 0x39,
+ 0xb1, 0xd6, 0xb4, 0x3a, 0xfb, 0x3a, 0xfe, 0x3a, 0xff, 0x62, 0x73, 0xff,
+ 0xc1, 0xa3, 0xac, 0xa8, 0x51, 0x13, 0x02, 0x89, 0xa2, 0x0b, 0xef, 0x46,
+ 0xf3, 0x9d, 0x7f, 0xde, 0xd6, 0x6f, 0x2e, 0x81, 0x43, 0xa9, 0x0f, 0x78,
+ 0x48, 0xef, 0xa3, 0x64, 0x48, 0xeb, 0xf7, 0x1a, 0xee, 0xd3, 0x44, 0x47,
+ 0x7f, 0xfd, 0xd0, 0x6b, 0x58, 0xb1, 0xcd, 0x9f, 0x21, 0x58, 0x3a, 0xff,
+ 0xa2, 0x7e, 0x67, 0xbc, 0x9e, 0x3a, 0xf0, 0xc6, 0xe7, 0x54, 0x8f, 0x4c,
+ 0x27, 0x17, 0xfd, 0x9c, 0xcd, 0x63, 0x8c, 0xe7, 0x5e, 0xc0, 0xac, 0xeb,
+ 0xff, 0xfd, 0xd7, 0x4f, 0x47, 0x47, 0x3d, 0xd4, 0xee, 0x23, 0x27, 0x5f,
+ 0xff, 0xfe, 0xf7, 0x91, 0x7c, 0x4c, 0xdc, 0x41, 0xe8, 0xef, 0xcd, 0x89,
+ 0xe9, 0xa0, 0xea, 0x84, 0x6c, 0x62, 0xed, 0xfe, 0x75, 0xe7, 0x25, 0x0b,
+ 0x3a, 0xe9, 0xd6, 0x55, 0xcc, 0xb2, 0x55, 0xff, 0x98, 0x6f, 0x52, 0x6e,
+ 0xc4, 0xec, 0x7e, 0x6b, 0xd9, 0x17, 0xbe, 0xd9, 0x1e, 0x83, 0xaa, 0x47,
+ 0xfa, 0x8b, 0x77, 0xf6, 0x3a, 0xf3, 0x7f, 0x1d, 0x7f, 0x9d, 0x8d, 0x27,
+ 0x1f, 0xf3, 0xac, 0xae, 0x75, 0xff, 0x46, 0x6f, 0x0f, 0x27, 0x91, 0xd4,
+ 0xac, 0x9e, 0x48, 0x44, 0xef, 0xe5, 0x71, 0xce, 0xbf, 0x8e, 0xbf, 0xa1,
+ 0x4c, 0x14, 0x50, 0xeb, 0xfb, 0x3d, 0xb5, 0xec, 0xe9, 0xd5, 0x88, 0x89,
+ 0x12, 0xed, 0x16, 0x5f, 0xff, 0xcd, 0x63, 0x8e, 0x29, 0xe6, 0x39, 0x1e,
+ 0x17, 0xfc, 0xea, 0x56, 0xd7, 0xac, 0x15, 0x50, 0xae, 0x88, 0x4c, 0x48,
+ 0x83, 0x08, 0x9a, 0x67, 0xbc, 0x2a, 0x90, 0x8a, 0x63, 0x6e, 0x43, 0xcf,
+ 0xa4, 0x2f, 0x0d, 0xdf, 0xc8, 0x44, 0xb3, 0x4f, 0x9e, 0x85, 0x86, 0xc2,
+ 0xeb, 0xb6, 0xba, 0x75, 0xfb, 0x8d, 0x77, 0x69, 0xa2, 0x2e, 0xbf, 0x7b,
+ 0xff, 0xa3, 0x22, 0xaf, 0xda, 0xf7, 0x63, 0xf3, 0xaf, 0xcf, 0x3c, 0x70,
+ 0x07, 0x59, 0x89, 0xd1, 0x8b, 0x83, 0x2e, 0x66, 0x02, 0xad, 0xb2, 0x8a,
+ 0x61, 0x51, 0x44, 0xa3, 0xd5, 0xbf, 0xf9, 0x6f, 0x26, 0x33, 0x8d, 0x77,
+ 0x69, 0xa2, 0x66, 0xbf, 0x95, 0x65, 0x68, 0xa8, 0xd4, 0x78, 0xeb, 0xdb,
+ 0xc6, 0x8e, 0xbc, 0xd4, 0x59, 0xd7, 0xca, 0xaf, 0x38, 0x9d, 0x76, 0xda,
+ 0xb2, 0x75, 0xd8, 0x03, 0xaf, 0xff, 0x76, 0x16, 0xfe, 0xcd, 0xff, 0x5f,
+ 0xde, 0x9d, 0x7f, 0x7b, 0x27, 0xcf, 0xe6, 0x3a, 0xff, 0x7c, 0xc1, 0x7e,
+ 0x7f, 0xb6, 0x75, 0xff, 0xf9, 0x6f, 0xdc, 0xdf, 0xfe, 0xb2, 0xfd, 0x9b,
+ 0xa0, 0x3a, 0x82, 0x89, 0x0c, 0x37, 0xbb, 0x58, 0x75, 0xdb, 0x5e, 0x3a,
+ 0xca, 0x93, 0xad, 0xfc, 0x1a, 0xd0, 0x0c, 0xdf, 0xff, 0xf9, 0x06, 0x1a,
+ 0x30, 0xbf, 0x91, 0xce, 0x26, 0xce, 0x3b, 0xfe, 0x75, 0x2b, 0x2a, 0x8d,
+ 0x9a, 0x3c, 0x82, 0xb3, 0x26, 0xf6, 0x17, 0xee, 0x45, 0xfa, 0x17, 0x89,
+ 0xef, 0xe6, 0x60, 0x47, 0x3c, 0x75, 0xf3, 0xf5, 0x26, 0x3a, 0xfb, 0xb3,
+ 0x40, 0x4e, 0xac, 0x3e, 0xe6, 0x95, 0xb9, 0x0d, 0xfe, 0x6a, 0x60, 0x87,
+ 0xb0, 0x75, 0x1d, 0x7e, 0xeb, 0xfa, 0x5f, 0x9d, 0x7f, 0xfb, 0xe7, 0x5d,
+ 0x3d, 0xf8, 0x04, 0x5e, 0x47, 0x56, 0x22, 0xb1, 0xa6, 0x08, 0x14, 0xb2,
+ 0x8b, 0xff, 0xff, 0xff, 0xff, 0xca, 0xbd, 0x51, 0x8a, 0xbd, 0x54, 0xad,
+ 0x15, 0xa3, 0x55, 0x30, 0xab, 0x95, 0x5c, 0x9f, 0x6b, 0x00, 0x15, 0x6b,
+ 0x1b, 0x7b, 0xfd, 0xea, 0xaa, 0x21, 0x54, 0xae, 0xab, 0x7b, 0xe7, 0xce,
+ 0xed, 0x9d, 0x7f, 0xfe, 0xff, 0x79, 0x74, 0x11, 0xc6, 0x3a, 0x8d, 0x7e,
+ 0x1d, 0x7f, 0xf6, 0xec, 0xc7, 0x82, 0x8a, 0xfa, 0x85, 0x9d, 0x7f, 0xff,
+ 0xe4, 0x5a, 0x73, 0xa0, 0xd4, 0xa3, 0x67, 0x20, 0x7d, 0xdc, 0x91, 0xd7,
+ 0xfe, 0x4f, 0x23, 0x50, 0x3e, 0xc6, 0x9d, 0x58, 0x8f, 0x0f, 0x24, 0x6d,
+ 0x36, 0x5f, 0x7b, 0x6f, 0x3a, 0x75, 0xff, 0xfe, 0x71, 0x68, 0xe0, 0x7a,
+ 0x0f, 0x9d, 0x89, 0x72, 0x27, 0x3a, 0xb1, 0x10, 0xa0, 0x24, 0xbf, 0xff,
+ 0xce, 0xa0, 0xe7, 0xe0, 0xd7, 0xc9, 0x27, 0x61, 0xa2, 0xe7, 0x5f, 0x79,
+ 0x3a, 0x87, 0x5f, 0xf3, 0xf2, 0x5f, 0x31, 0xa1, 0xc3, 0xa9, 0x54, 0xb8,
+ 0x0d, 0x11, 0x95, 0xe4, 0x69, 0x1d, 0x85, 0xbb, 0x91, 0x0b, 0x08, 0x08,
+ 0x2d, 0xc3, 0xaf, 0xef, 0x62, 0xf7, 0xc5, 0x9d, 0x6e, 0xe1, 0xbd, 0x41,
+ 0x0b, 0xfc, 0x00, 0xbc, 0xb4, 0x92, 0x3a, 0xff, 0xfc, 0x14, 0x19, 0xf3,
+ 0x48, 0xfd, 0x61, 0x96, 0x59, 0x2a, 0xfe, 0xf7, 0x62, 0x7e, 0x80, 0xeb,
+ 0xfb, 0x79, 0x6b, 0xf0, 0x4c, 0x75, 0xff, 0x4f, 0x9f, 0x84, 0x0f, 0xc9,
+ 0x1d, 0x79, 0xdd, 0xa6, 0x8b, 0x3e, 0xfe, 0xfd, 0xc6, 0x48, 0xb3, 0xaa,
+ 0x74, 0x46, 0xb4, 0xeb, 0xf2, 0x7b, 0xff, 0x27, 0x62, 0x49, 0xe8, 0xf6,
+ 0x8e, 0xbf, 0xfd, 0xce, 0xbf, 0xcc, 0xd8, 0x39, 0xac, 0x13, 0xaf, 0xfe,
+ 0xd7, 0x92, 0x66, 0x5c, 0x31, 0xbe, 0x8e, 0xa4, 0x44, 0x80, 0x12, 0xaf,
+ 0x32, 0xcb, 0x25, 0x5f, 0xf9, 0xe5, 0xa1, 0xc6, 0x87, 0x38, 0x53, 0x05,
+ 0xfd, 0xfb, 0x68, 0x0b, 0xc0, 0x9d, 0x7f, 0xbd, 0xdc, 0xd9, 0xf2, 0x4b,
+ 0x3a, 0xb0, 0xf8, 0x40, 0x55, 0x7f, 0xed, 0xe4, 0x20, 0xff, 0xe3, 0x57,
+ 0xf9, 0xd7, 0x42, 0x87, 0x54, 0x1e, 0xd4, 0xe8, 0x97, 0xfb, 0xa8, 0x11,
+ 0x77, 0x98, 0xeb, 0xfc, 0x1e, 0x81, 0xff, 0xdb, 0xc3, 0xaa, 0x0f, 0x9d,
+ 0x0c, 0x6f, 0xf9, 0x04, 0x3f, 0x42, 0x0f, 0x68, 0xeb, 0xd0, 0x2a, 0x1d,
+ 0x52, 0x5d, 0x00, 0x09, 0x2b, 0x4c, 0xb7, 0x58, 0x98, 0xbb, 0x90, 0xbe,
+ 0x59, 0x97, 0x61, 0x99, 0xfa, 0x08, 0xc2, 0xb7, 0x4f, 0x7e, 0x84, 0x4e,
+ 0xc2, 0x0f, 0xa7, 0x57, 0xfd, 0xc7, 0x67, 0xa9, 0x1c, 0x83, 0xaf, 0xfd,
+ 0xc4, 0xd4, 0xbe, 0xf6, 0x06, 0x0e, 0xbe, 0xe2, 0x42, 0xce, 0xbf, 0xff,
+ 0x79, 0x40, 0x46, 0x07, 0xb9, 0xad, 0xe5, 0x1d, 0x3a, 0xb8, 0x8b, 0x45,
+ 0x9f, 0x09, 0x05, 0xcf, 0x23, 0xaf, 0xff, 0xff, 0xe1, 0x76, 0x7d, 0x9d,
+ 0x1c, 0xf0, 0x3f, 0x5b, 0xc9, 0xc3, 0x02, 0xfc, 0x79, 0x1d, 0x7f, 0xb3,
+ 0xbd, 0x07, 0x9c, 0x4e, 0xbe, 0x5a, 0x4d, 0xa3, 0xac, 0x81, 0x47, 0x6c,
+ 0xc2, 0xbc, 0x84, 0x2a, 0xcc, 0x6f, 0xdc, 0x9b, 0x66, 0x04, 0xeb, 0xff,
+ 0x63, 0x3b, 0x5c, 0xcd, 0xa1, 0x03, 0x27, 0x54, 0x27, 0xa7, 0xd8, 0xc7,
+ 0x1d, 0x20, 0x4a, 0xaf, 0xff, 0xff, 0xbf, 0xd6, 0x60, 0xa9, 0xf7, 0x83,
+ 0x19, 0xd6, 0x34, 0x39, 0x3a, 0xf1, 0x67, 0x5f, 0xbe, 0xc0, 0xfd, 0x59,
+ 0xd5, 0x88, 0xa9, 0xf3, 0xfd, 0xfb, 0x63, 0xf6, 0x3e, 0x9d, 0x58, 0x79,
+ 0x88, 0x45, 0x7b, 0x51, 0x39, 0xd7, 0xfd, 0x18, 0xde, 0xa6, 0xc7, 0xe1,
+ 0xd7, 0x67, 0x4e, 0xa1, 0x3c, 0xdd, 0xb3, 0x8a, 0x92, 0x2b, 0x74, 0x41,
+ 0xe6, 0x9b, 0xdd, 0x03, 0x27, 0x5e, 0xfc, 0x0d, 0x3a, 0xf7, 0xb3, 0xe9,
+ 0xd7, 0xf4, 0x6f, 0xaf, 0x9c, 0x83, 0xaf, 0x04, 0x0d, 0x3a, 0xf8, 0x23,
+ 0x12, 0x3a, 0x90, 0xde, 0x38, 0xe5, 0x05, 0x1c, 0x3b, 0x8e, 0xa0, 0xea,
+ 0xc7, 0x7a, 0xd7, 0x76, 0x34, 0xeb, 0xfb, 0x89, 0xb3, 0x07, 0x47, 0x5f,
+ 0xdb, 0xfb, 0x3a, 0x05, 0x73, 0xaf, 0xee, 0x67, 0x7a, 0x0f, 0x1d, 0x7e,
+ 0xe8, 0xc6, 0x70, 0xcb, 0xfb, 0x39, 0x38, 0x1c, 0x26, 0x88, 0x35, 0x83,
+ 0x4b, 0x6e, 0x4e, 0x89, 0xd9, 0x29, 0x54, 0x23, 0xe1, 0x21, 0x9d, 0x7e,
+ 0x76, 0xa2, 0xe0, 0xeb, 0xfa, 0x5d, 0x17, 0xdf, 0xc7, 0x5b, 0x1a, 0x7a,
+ 0x42, 0x4b, 0x7e, 0x8f, 0x7c, 0x5b, 0x27, 0x5f, 0xe9, 0x22, 0xe3, 0xbf,
+ 0x42, 0x75, 0xff, 0xe8, 0xc1, 0xdf, 0xd9, 0xc4, 0x9d, 0xd6, 0x75, 0xf9,
+ 0xd9, 0xf6, 0x77, 0x47, 0xf9, 0xe3, 0x4a, 0x56, 0xd5, 0x5e, 0xc0, 0xac,
+ 0xa3, 0x25, 0xc7, 0x8e, 0x13, 0x0c, 0x29, 0xaf, 0x6b, 0x24, 0x75, 0xf9,
+ 0x37, 0x92, 0x09, 0xd7, 0x93, 0xb8, 0x75, 0xd0, 0xbc, 0x3c, 0x06, 0x93,
+ 0x5f, 0x07, 0x5d, 0x83, 0xaf, 0xc3, 0xc6, 0x5e, 0x73, 0xab, 0x0f, 0x25,
+ 0xc8, 0x6e, 0x00, 0x9d, 0x50, 0x98, 0x2a, 0x2d, 0xf1, 0xd7, 0x44, 0x17,
+ 0xbb, 0x82, 0x75, 0xfe, 0x9a, 0x27, 0x5b, 0xcd, 0x07, 0x5f, 0xff, 0x3a,
+ 0x9e, 0x8e, 0x7f, 0xc8, 0xf0, 0xbf, 0xe7, 0x5f, 0xff, 0xc2, 0xea, 0x7c,
+ 0xfa, 0x2f, 0xed, 0x26, 0xfd, 0x46, 0x4e, 0xac, 0x47, 0xeb, 0x8d, 0x09,
+ 0xa0, 0x14, 0x2e, 0xd6, 0xc3, 0xaf, 0x90, 0x5c, 0x27, 0x5f, 0xf9, 0x79,
+ 0xed, 0x7d, 0xd3, 0xcb, 0x0e, 0xbf, 0x6a, 0x39, 0xe8, 0x39, 0x83, 0x7f,
+ 0x41, 0x44, 0xae, 0x97, 0xaf, 0xdf, 0x66, 0x77, 0xe1, 0xd7, 0xdd, 0xc4,
+ 0xd8, 0x75, 0xfd, 0xa4, 0xe6, 0x03, 0x87, 0x5f, 0xff, 0xe8, 0x9b, 0xe2,
+ 0x34, 0x1c, 0xd0, 0x3e, 0x2d, 0x3d, 0xd4, 0x3a, 0xb1, 0x3a, 0xc4, 0x85,
+ 0x6a, 0xc8, 0xfa, 0x53, 0xe2, 0x2d, 0xa2, 0xcb, 0x96, 0xa8, 0x34, 0x5f,
+ 0x97, 0xda, 0xe6, 0x61, 0xd7, 0xff, 0x4b, 0xc0, 0x94, 0x97, 0xef, 0x42,
+ 0xce, 0xbf, 0xde, 0xd4, 0x4f, 0x9a, 0x09, 0xd7, 0x77, 0x0e, 0xbf, 0xfe,
+ 0xec, 0x07, 0x1b, 0xf3, 0x07, 0x03, 0xd8, 0x3a, 0xff, 0xe4, 0xc1, 0xcc,
+ 0xd7, 0xc9, 0x69, 0x67, 0x5f, 0xf9, 0xe3, 0x79, 0x7c, 0xd6, 0xe1, 0x83,
+ 0xa8, 0x29, 0xbf, 0xee, 0x40, 0x88, 0xaa, 0xe6, 0x73, 0x0a, 0xe9, 0x3b,
+ 0xc8, 0x77, 0x94, 0x8e, 0x1d, 0x7f, 0x06, 0x3f, 0xe6, 0x6e, 0x75, 0x30,
+ 0x79, 0x4b, 0x1c, 0xbf, 0xd0, 0xbc, 0x4e, 0x4d, 0x23, 0xae, 0x49, 0x8e,
+ 0xbf, 0xfd, 0xe8, 0xe8, 0xbc, 0xf1, 0xce, 0x3c, 0x8e, 0xbd, 0xe4, 0x9c,
+ 0xeb, 0xf7, 0xef, 0xbc, 0x4c, 0x75, 0xe1, 0x86, 0x9d, 0x7f, 0xf0, 0x52,
+ 0x6e, 0xc7, 0x37, 0x94, 0x70, 0xeb, 0xff, 0x85, 0xf7, 0xd6, 0xb3, 0x81,
+ 0xee, 0x1d, 0x7f, 0xfa, 0x1b, 0xf3, 0x98, 0x80, 0x54, 0xe6, 0xd6, 0x1d,
+ 0x48, 0x89, 0x31, 0x43, 0xaf, 0x89, 0xdb, 0x20, 0xb2, 0xd2, 0x1c, 0x70,
+ 0x4a, 0x74, 0x35, 0xb5, 0x0d, 0x8b, 0x41, 0xd7, 0xba, 0x9e, 0x3a, 0xdb,
+ 0x30, 0xd5, 0x7d, 0x0f, 0xa8, 0x5d, 0x82, 0x0a, 0xf6, 0x47, 0x4c, 0x90,
+ 0xb3, 0xe9, 0x1b, 0xc7, 0xd1, 0xfc, 0x25, 0xaf, 0xfb, 0x06, 0x43, 0x8b,
+ 0x86, 0x9d, 0x7e, 0xea, 0x6c, 0xc0, 0x9d, 0x7f, 0xe0, 0xc0, 0xe0, 0x82,
+ 0x59, 0xa3, 0xaf, 0xce, 0xb4, 0xda, 0xc3, 0xaf, 0x7a, 0x37, 0x3a, 0xb0,
+ 0xf1, 0x1c, 0xa2, 0xf4, 0x24, 0xc7, 0x5e, 0x15, 0x67, 0x68, 0xeb, 0xf6,
+ 0x4e, 0xb8, 0xd1, 0xd7, 0xff, 0xfe, 0x8e, 0xa2, 0xd8, 0x9a, 0x4f, 0xcf,
+ 0xbd, 0x4d, 0xf4, 0xd4, 0x9c, 0xea, 0x0a, 0x7a, 0x4a, 0x1a, 0xa1, 0x44,
+ 0xcf, 0xfd, 0x20, 0x11, 0xbd, 0x11, 0xed, 0x13, 0xdf, 0xcf, 0xc8, 0xef,
+ 0xd0, 0x9d, 0x7d, 0x09, 0x3c, 0x1d, 0x7c, 0xcb, 0xe6, 0x8e, 0xbf, 0xe9,
+ 0x2d, 0xe5, 0xed, 0x42, 0x87, 0x54, 0x1e, 0xd3, 0x90, 0xde, 0xd2, 0x09,
+ 0xd7, 0xe1, 0x6f, 0xcd, 0x6e, 0x75, 0x61, 0xe2, 0x38, 0xd5, 0x3a, 0x65,
+ 0x9f, 0x97, 0x0b, 0xd0, 0x19, 0x2e, 0x9e, 0x47, 0x5e, 0x4e, 0xa1, 0xd5,
+ 0xb9, 0xb1, 0xf0, 0xbd, 0xf7, 0xd0, 0x3e, 0x8e, 0xbf, 0xd2, 0x00, 0xcf,
+ 0xa4, 0xdc, 0xeb, 0xef, 0xff, 0xcd, 0xce, 0xbf, 0xb6, 0xbd, 0x8e, 0x2d,
+ 0x3a, 0xff, 0x80, 0xf2, 0x0e, 0x67, 0xfa, 0x3a, 0xff, 0x7e, 0x9b, 0xef,
+ 0x2c, 0xf1, 0xd5, 0xd3, 0xed, 0xd1, 0xc5, 0xfb, 0x7d, 0x2d, 0x15, 0xce,
+ 0xbf, 0xff, 0x66, 0xbe, 0x75, 0xd3, 0xdf, 0x80, 0x45, 0xe4, 0x75, 0x42,
+ 0x20, 0x04, 0xae, 0xfe, 0x79, 0xff, 0x71, 0x09, 0xd5, 0x32, 0x7c, 0x7c,
+ 0x34, 0xe9, 0x27, 0xa1, 0x37, 0xb2, 0x14, 0x5b, 0x64, 0x37, 0xfd, 0xdf,
+ 0xb0, 0xdd, 0xbc, 0xe4, 0x1d, 0x50, 0xaa, 0xab, 0x25, 0x03, 0x3b, 0x45,
+ 0xd3, 0x00, 0xeb, 0x2c, 0xea, 0xdc, 0xd3, 0xaa, 0x45, 0xef, 0xfe, 0x8e,
+ 0x66, 0xc7, 0x97, 0xf9, 0x81, 0x3a, 0xfe, 0x7d, 0xe4, 0x30, 0x13, 0xaf,
+ 0xfa, 0x37, 0x92, 0x0a, 0xdf, 0xc7, 0x53, 0x9f, 0x18, 0x96, 0x5f, 0x9e,
+ 0x59, 0x3c, 0x1d, 0x7f, 0xf4, 0x6b, 0x58, 0xbf, 0x0c, 0x2f, 0x47, 0x5f,
+ 0xfc, 0x91, 0xa1, 0x79, 0x7c, 0xd6, 0x70, 0xeb, 0xff, 0xfc, 0x9a, 0x9f,
+ 0x19, 0xc1, 0x06, 0xd4, 0x31, 0x82, 0xfc, 0x3a, 0xff, 0x6f, 0x2d, 0x4d,
+ 0x28, 0x9c, 0xea, 0x0a, 0x68, 0x6d, 0x26, 0x14, 0x2f, 0x21, 0x81, 0x8a,
+ 0xff, 0xff, 0xdd, 0x4d, 0xfd, 0x9b, 0xfb, 0x9c, 0x8f, 0x7f, 0xf4, 0x65,
+ 0xdc, 0x3a, 0xf8, 0x21, 0x71, 0x3a, 0xff, 0xd2, 0x81, 0xf7, 0x13, 0x66,
+ 0x04, 0xeb, 0xff, 0x3f, 0x5a, 0x8f, 0xf3, 0x4f, 0xd3, 0xaf, 0xff, 0xda,
+ 0x1f, 0x9d, 0x74, 0xf7, 0xe0, 0x11, 0x79, 0x1d, 0x7f, 0xba, 0x8a, 0x6d,
+ 0x83, 0x8a, 0x1d, 0x7f, 0xd0, 0xca, 0xfb, 0x08, 0x33, 0x9d, 0x7f, 0xfc,
+ 0x39, 0xac, 0x5c, 0x37, 0x3c, 0x9c, 0xc3, 0xad, 0x8d, 0x45, 0xdf, 0x8e,
+ 0x36, 0x1c, 0x5f, 0xd3, 0xe7, 0x11, 0xb0, 0x75, 0xf0, 0x86, 0x16, 0x75,
+ 0xfb, 0x66, 0x08, 0x1c, 0xeb, 0xf9, 0xff, 0xc0, 0xbc, 0x8e, 0xa8, 0x3f,
+ 0x3c, 0x20, 0x42, 0x7a, 0x44, 0x65, 0xf6, 0x13, 0xf5, 0x0b, 0xb7, 0xf3,
+ 0x93, 0x06, 0x14, 0xf9, 0x1b, 0x1b, 0x52, 0x91, 0xc2, 0x62, 0x0e, 0x9f,
+ 0x7e, 0x7c, 0x31, 0x88, 0x7a, 0x30, 0x2b, 0xff, 0xb0, 0x7f, 0xcc, 0xe6,
+ 0xbd, 0x18, 0x75, 0xff, 0x6f, 0xec, 0xe2, 0x4e, 0xeb, 0x3a, 0xd9, 0xf9,
+ 0xfd, 0x0a, 0x0d, 0xe5, 0x4c, 0x90, 0xeb, 0xe8, 0x17, 0x91, 0xd7, 0xec,
+ 0x57, 0x71, 0xff, 0xe1, 0xbe, 0xe0, 0xfd, 0xfd, 0xb3, 0xa9, 0x1c, 0xd1,
+ 0xd7, 0xff, 0xe8, 0x19, 0x67, 0x51, 0x61, 0xc9, 0xa3, 0x38, 0x75, 0xf3,
+ 0x7a, 0x93, 0x1d, 0x7f, 0xfe, 0x1c, 0x51, 0x44, 0x0f, 0x52, 0x6e, 0xa6,
+ 0xfe, 0x3a, 0xa0, 0xfe, 0x70, 0x8a, 0xf3, 0x5f, 0x87, 0x5f, 0xb4, 0xd8,
+ 0xe2, 0x87, 0x57, 0x4f, 0x0f, 0xf1, 0xbb, 0xfd, 0x92, 0xc4, 0x0f, 0x50,
+ 0xeb, 0xef, 0x49, 0x7d, 0x3a, 0xf9, 0x14, 0x46, 0x4e, 0xac, 0x3c, 0x41,
+ 0x22, 0xbb, 0xe6, 0x1d, 0x7d, 0xa1, 0x85, 0x9d, 0x50, 0x6d, 0xf7, 0x17,
+ 0xbe, 0xce, 0xc9, 0x67, 0x54, 0x2b, 0x33, 0x93, 0x2e, 0x21, 0x28, 0x5d,
+ 0xd8, 0x65, 0xbb, 0x18, 0x91, 0xe9, 0xd0, 0x0a, 0xfb, 0x64, 0x37, 0x82,
+ 0xb6, 0x9d, 0x6e, 0x9d, 0x76, 0xa4, 0x75, 0x7e, 0x69, 0x80, 0x21, 0x7f,
+ 0x4f, 0x34, 0x95, 0x5c, 0x9c, 0xeb, 0xcf, 0x9c, 0x3a, 0xf0, 0xe7, 0x8e,
+ 0xae, 0x9b, 0x41, 0x1a, 0xbb, 0xc2, 0x75, 0xe8, 0xdf, 0x47, 0x5f, 0x20,
+ 0xcb, 0x0e, 0xbd, 0x3b, 0x89, 0xd4, 0x13, 0xd6, 0x58, 0xe7, 0x87, 0xef,
+ 0xd9, 0xee, 0xa7, 0x8e, 0xbf, 0x3e, 0xf9, 0xbf, 0x8e, 0xb2, 0x9d, 0x3c,
+ 0xef, 0x13, 0x5c, 0x9c, 0x3a, 0xfe, 0x9f, 0xe4, 0xee, 0xfd, 0x3a, 0x95,
+ 0x94, 0xf7, 0xe1, 0xa6, 0x44, 0x18, 0xd6, 0x8f, 0xbd, 0x29, 0x71, 0x5b,
+ 0xfe, 0xc0, 0x85, 0x37, 0xcd, 0xfc, 0x75, 0xf3, 0x46, 0x24, 0x75, 0x74,
+ 0xf6, 0x5c, 0xe6, 0xff, 0x46, 0x7a, 0x3a, 0xe1, 0x3a, 0xa7, 0x3d, 0x10,
+ 0x90, 0xdf, 0xfc, 0x18, 0x0f, 0x23, 0xc8, 0xd4, 0x09, 0xd7, 0xd3, 0x46,
+ 0xd4, 0x8e, 0xbf, 0xbc, 0xd0, 0x85, 0x7c, 0x3a, 0xff, 0xa6, 0xd6, 0xc7,
+ 0x19, 0xc0, 0x13, 0xaf, 0xb3, 0xd8, 0xb3, 0xae, 0x15, 0x0e, 0xb6, 0x9c,
+ 0xdb, 0x00, 0x82, 0xfe, 0xe8, 0x27, 0x9b, 0xa8, 0x75, 0xf0, 0x8e, 0x78,
+ 0xea, 0x84, 0xe7, 0x82, 0x47, 0x88, 0x4a, 0x12, 0xa1, 0x74, 0xce, 0x5d,
+ 0x26, 0xf1, 0x7d, 0xfd, 0xf2, 0x68, 0xf0, 0xec, 0x3a, 0xff, 0xf0, 0xc6,
+ 0xce, 0x47, 0x31, 0x3b, 0x01, 0x3a, 0xf0, 0xba, 0xce, 0xa9, 0x22, 0x4f,
+ 0x0c, 0x51, 0x22, 0xcc, 0x2b, 0x2e, 0xe9, 0xf9, 0x5b, 0x3c, 0x56, 0x83,
+ 0x8a, 0xd4, 0x6e, 0x25, 0x2d, 0x4f, 0x0e, 0xb9, 0x43, 0x64, 0x33, 0x88,
+ 0x39, 0x3b, 0x6a, 0xa4, 0x37, 0x1b, 0x2a, 0xfb, 0x78, 0xf8, 0xd2, 0x31,
+ 0x19, 0xa5, 0x83, 0xf2, 0x36, 0xb5, 0xc6, 0x73, 0xd9, 0xf6, 0x87, 0x94,
+ 0x99, 0xfc, 0x74, 0x2a, 0x96, 0xe1, 0x95, 0x99, 0xa9, 0xe1, 0xcf, 0x4e,
+ 0x2f, 0x02, 0x12, 0x4c, 0xa1, 0x6d, 0xca, 0x01, 0xfb, 0x2a, 0xbb, 0x6a,
+ 0x30, 0x4a, 0x61, 0xde, 0x82, 0x76, 0xdd, 0x67, 0x5f, 0xfe, 0x61, 0x6f,
+ 0x26, 0x33, 0x8d, 0x77, 0x69, 0xa2, 0x6c, 0xbf, 0xcc, 0x67, 0x1a, 0xee,
+ 0xd3, 0x45, 0x5b, 0x7f, 0xa5, 0x20, 0x78, 0x62, 0x47, 0x5f, 0x67, 0x5f,
+ 0xc7, 0x59, 0x51, 0x87, 0xa4, 0x26, 0x57, 0xfb, 0x98, 0xd8, 0xff, 0xea,
+ 0xce, 0xbf, 0xe8, 0xec, 0x4f, 0xc8, 0xc0, 0x9d, 0x5c, 0x3e, 0xce, 0x9a,
+ 0xdf, 0xa3, 0x8b, 0xe8, 0x4e, 0xbc, 0x1c, 0x13, 0xaf, 0x3b, 0xb4, 0xd1,
+ 0x5a, 0x5f, 0x94, 0xdf, 0x40, 0xdc, 0xea, 0x69, 0xe9, 0x21, 0x3d, 0xff,
+ 0xe4, 0xf4, 0xa1, 0xbd, 0x4f, 0x69, 0xf7, 0x3a, 0xb8, 0x7d, 0x5b, 0x08,
+ 0x6f, 0xff, 0x75, 0x17, 0x0d, 0xc5, 0xe0, 0xfb, 0x6c, 0xeb, 0xff, 0xe6,
+ 0xc7, 0x33, 0xf7, 0x5b, 0xca, 0x11, 0xa7, 0x5f, 0xff, 0x4b, 0x58, 0x30,
+ 0xb7, 0xcf, 0x7a, 0x16, 0x75, 0xde, 0xf4, 0x22, 0x65, 0xd3, 0x6f, 0xff,
+ 0xff, 0x46, 0xc4, 0xf6, 0xb1, 0x46, 0xf5, 0x3d, 0x93, 0x0c, 0x2e, 0x7c,
+ 0x64, 0xeb, 0xfd, 0x1e, 0x7e, 0xfc, 0x0c, 0x1d, 0x7d, 0x2f, 0x24, 0xe7,
+ 0x5f, 0xbe, 0xf8, 0x63, 0xf3, 0xab, 0x73, 0xcb, 0xd8, 0x45, 0x7f, 0x9e,
+ 0x5e, 0x49, 0xfa, 0x87, 0x54, 0x1e, 0xba, 0x12, 0xdf, 0xb3, 0xa9, 0x8b,
+ 0x3a, 0xff, 0xe1, 0x74, 0x6f, 0x5c, 0x13, 0xf1, 0x0e, 0xa9, 0xcf, 0x9f,
+ 0xa4, 0xb7, 0xfa, 0x51, 0xc9, 0xe3, 0x93, 0x9d, 0x7b, 0x39, 0xf9, 0xd7,
+ 0xe9, 0xb0, 0x2b, 0x57, 0x3a, 0xfe, 0x18, 0x67, 0x79, 0x68, 0xea, 0x43,
+ 0xf5, 0x98, 0x73, 0x68, 0xae, 0xa1, 0x1b, 0x79, 0x0a, 0x9b, 0xff, 0xff,
+ 0xfb, 0x11, 0xb9, 0xe8, 0x1f, 0x6b, 0xe4, 0x20, 0x71, 0x7f, 0x39, 0x09,
+ 0x27, 0xd1, 0xd7, 0xf6, 0x79, 0xc7, 0xf0, 0x1d, 0x7f, 0x77, 0xe2, 0x4e,
+ 0xe2, 0x75, 0x48, 0xf6, 0xb0, 0xb2, 0xcc, 0x2a, 0x97, 0xb9, 0x62, 0x12,
+ 0xd3, 0x91, 0x04, 0x9f, 0x21, 0xac, 0xd2, 0x44, 0x87, 0x1f, 0x0b, 0x56,
+ 0xf5, 0xd8, 0x6a, 0xbc, 0x21, 0xc6, 0x1f, 0xda, 0x26, 0xf4, 0x38, 0x6f,
+ 0xf3, 0x19, 0xc6, 0xbb, 0xb4, 0xd1, 0x60, 0x5f, 0xb8, 0xd7, 0x76, 0x9a,
+ 0x27, 0x5b, 0xff, 0xfd, 0xd8, 0x9c, 0x38, 0xb6, 0x35, 0xac, 0xea, 0x68,
+ 0x13, 0x9d, 0x7e, 0x61, 0x6f, 0x26, 0x31, 0x12, 0xd3, 0x19, 0xdf, 0xe9,
+ 0x69, 0x85, 0x14, 0x85, 0x9d, 0x7e, 0xe3, 0x5d, 0xda, 0x68, 0xb6, 0x6f,
+ 0xff, 0xf3, 0xc9, 0x8d, 0x42, 0x60, 0x53, 0x35, 0x9e, 0x18, 0x3a, 0xff,
+ 0xdf, 0xc6, 0x98, 0xea, 0x35, 0xf8, 0x75, 0xff, 0x44, 0xa3, 0x93, 0xc7,
+ 0x27, 0x3a, 0xcc, 0x62, 0x60, 0xeb, 0x33, 0x75, 0xc1, 0x3f, 0xbf, 0xff,
+ 0x3f, 0xff, 0x83, 0x4c, 0x67, 0x1f, 0x5d, 0x79, 0x1d, 0x7c, 0xd7, 0x76,
+ 0x9a, 0x2e, 0x6b, 0x2c, 0xea, 0xe1, 0xbd, 0x64, 0xb6, 0xff, 0x70, 0x73,
+ 0x7f, 0xd2, 0x47, 0x5d, 0x32, 0xce, 0xa3, 0xac, 0xc6, 0x1f, 0xb2, 0x11,
+ 0x32, 0x67, 0xb6, 0x2f, 0x7e, 0xe3, 0x5d, 0xda, 0x68, 0xbb, 0xef, 0xf4,
+ 0x98, 0xd7, 0x38, 0x8c, 0x9d, 0x66, 0x30, 0xfa, 0x1c, 0xce, 0xf9, 0x85,
+ 0x03, 0xf9, 0xd5, 0x0f, 0x95, 0x6f, 0x96, 0xf4, 0xc1, 0xa6, 0xbb, 0xab,
+ 0xa4, 0xfb, 0xb7, 0x21, 0xd8, 0xb8, 0x6a, 0xba, 0x17, 0xf1, 0x9e, 0x8a,
+ 0x16, 0xa3, 0x0a, 0xf4, 0x2b, 0x7e, 0x93, 0xdf, 0xf9, 0x97, 0x19, 0xf4,
+ 0x83, 0xbc, 0x8e, 0xbf, 0xfb, 0x27, 0xc6, 0x7b, 0x9a, 0xc4, 0x13, 0xae,
+ 0x46, 0x3a, 0x88, 0x11, 0x3f, 0xbf, 0x6b, 0x4b, 0x79, 0x1d, 0x7f, 0xff,
+ 0xff, 0xee, 0xa7, 0x52, 0x07, 0xc2, 0xea, 0x67, 0x81, 0xe4, 0xf6, 0xba,
+ 0x9c, 0x89, 0xdf, 0x8d, 0x3a, 0xed, 0x41, 0xd7, 0xff, 0x6e, 0xd0, 0x3e,
+ 0xfe, 0xcc, 0x15, 0x0e, 0xbc, 0x2e, 0xc4, 0x26, 0x30, 0xd2, 0x7d, 0x42,
+ 0x5f, 0xc2, 0xb7, 0x80, 0xeb, 0x3a, 0xfd, 0x9b, 0x5e, 0x85, 0x0e, 0xb6,
+ 0xd1, 0xd5, 0x39, 0xbd, 0xc2, 0xaa, 0xe1, 0xfc, 0x8a, 0xc5, 0xff, 0xb4,
+ 0xea, 0x75, 0x20, 0x41, 0x07, 0x5f, 0xfb, 0xaf, 0xe7, 0xee, 0xf2, 0xcf,
+ 0x1d, 0x58, 0x7f, 0x48, 0x79, 0x73, 0xfe, 0x75, 0xff, 0xff, 0xe1, 0x76,
+ 0x47, 0x3d, 0xec, 0x9e, 0x05, 0xd4, 0xd2, 0xe3, 0x04, 0x27, 0x56, 0x22,
+ 0x2b, 0x82, 0xd7, 0xfb, 0xb8, 0x14, 0xd9, 0xcc, 0x3a, 0xf3, 0xbb, 0x4d,
+ 0x12, 0xbd, 0xfe, 0x51, 0xc7, 0xff, 0x67, 0x4e, 0xa6, 0x9e, 0xd2, 0x13,
+ 0xdf, 0xfe, 0xf7, 0x72, 0x4d, 0xea, 0x06, 0x07, 0xc7, 0x54, 0x91, 0xed,
+ 0xc8, 0x46, 0x89, 0x0d, 0xd2, 0x9c, 0xeb, 0xff, 0x0b, 0xb2, 0x1e, 0xc4,
+ 0xf8, 0xc9, 0xd7, 0xff, 0xec, 0x4f, 0xf1, 0x69, 0xed, 0x42, 0xdf, 0x7f,
+ 0x1d, 0x7f, 0xd0, 0xbf, 0x64, 0xd2, 0x4f, 0x1d, 0x52, 0x44, 0x67, 0x95,
+ 0x2f, 0x80, 0xfc, 0x91, 0xd7, 0xfd, 0x0d, 0x18, 0x9f, 0xf7, 0xf1, 0xd7,
+ 0xff, 0xf9, 0x3c, 0xeb, 0x71, 0xff, 0xac, 0xb8, 0xce, 0xd4, 0x9c, 0xea,
+ 0x0a, 0x2e, 0x90, 0x85, 0xce, 0x2f, 0xf8, 0x1f, 0xad, 0xe5, 0xae, 0x04,
+ 0xeb, 0xff, 0xfd, 0x88, 0x3e, 0xc1, 0xf8, 0x2e, 0x18, 0x19, 0xe3, 0x87,
+ 0x5b, 0x3c, 0x89, 0x7d, 0x87, 0x57, 0xfd, 0xbf, 0xf9, 0xcc, 0xcf, 0x68,
+ 0xea, 0x0a, 0xad, 0x0c, 0x86, 0x5f, 0x61, 0xba, 0x30, 0xc5, 0xfa, 0x55,
+ 0x7f, 0xef, 0x3c, 0xb5, 0xd8, 0xe7, 0xd0, 0x9d, 0x7f, 0xf7, 0x93, 0x62,
+ 0x7a, 0x69, 0x40, 0xf8, 0xeb, 0xff, 0xcf, 0x92, 0xee, 0x20, 0xe7, 0xfb,
+ 0x78, 0x75, 0xe7, 0x93, 0x10, 0xbd, 0x43, 0x28, 0x4d, 0x86, 0x15, 0x59,
+ 0x18, 0xc2, 0xcd, 0x35, 0x2b, 0x9f, 0xcb, 0x7f, 0x50, 0x36, 0x91, 0x6f,
+ 0xff, 0x67, 0x58, 0x1c, 0x0a, 0x0f, 0xb3, 0xa7, 0x5e, 0xf4, 0x04, 0xab,
+ 0xff, 0xdd, 0x74, 0xf4, 0x49, 0x39, 0x38, 0x3f, 0x2a, 0xff, 0x3b, 0x58,
+ 0x0f, 0x15, 0x2c, 0x41, 0xf2, 0xe8, 0x6e, 0xcc, 0x05, 0x94, 0xb8, 0xd8,
+ 0xd1, 0x97, 0x3e, 0xdb, 0xe8, 0x56, 0xec, 0x85, 0x65, 0xff, 0xe6, 0x16,
+ 0xf2, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x26, 0x1b, 0xff, 0xfb, 0x36, 0x38,
+ 0x7b, 0x0c, 0x7b, 0xb8, 0x10, 0x7b, 0x47, 0x5f, 0xfe, 0xe3, 0xfe, 0xc2,
+ 0x9e, 0x93, 0x31, 0xa9, 0x1d, 0x76, 0x30, 0x28, 0xab, 0xfa, 0xbb, 0x7f,
+ 0xf2, 0xa3, 0x37, 0x90, 0x1f, 0xc3, 0x12, 0x3a, 0xfd, 0x8b, 0xf9, 0xba,
+ 0xb9, 0xd7, 0xf4, 0x2f, 0x3f, 0x8d, 0x87, 0x50, 0x4f, 0x6f, 0xa5, 0xb7,
+ 0xfb, 0x98, 0xd8, 0xff, 0xea, 0xce, 0xbf, 0x76, 0x02, 0x8a, 0x1d, 0x48,
+ 0x7f, 0xdc, 0x22, 0xda, 0x35, 0xbf, 0xd0, 0xf3, 0xf9, 0x47, 0xe1, 0xd7,
+ 0xe7, 0xe4, 0x9d, 0x67, 0x50, 0x9e, 0xc8, 0x0c, 0xef, 0xff, 0xc9, 0xce,
+ 0xbf, 0xc0, 0xe4, 0xbb, 0x1b, 0x03, 0x07, 0x5f, 0xf3, 0x3f, 0x7b, 0x0d,
+ 0xea, 0x4c, 0x75, 0xf0, 0x17, 0x81, 0x3a, 0xd9, 0xb9, 0xee, 0xed, 0x1e,
+ 0x57, 0x51, 0xbe, 0x30, 0xb4, 0xbf, 0x97, 0x18, 0x3e, 0xdb, 0x3a, 0xda,
+ 0x3a, 0xfd, 0x18, 0x3e, 0xdb, 0x3a, 0xfe, 0xea, 0x7b, 0x4f, 0xbf, 0xc3,
+ 0xe6, 0x98, 0xb9, 0x62, 0x17, 0xfa, 0x5e, 0x85, 0xec, 0xfe, 0x47, 0x5f,
+ 0xff, 0xe6, 0x76, 0xbd, 0x9d, 0xf8, 0x39, 0x3a, 0x60, 0xef, 0x2d, 0x1d,
+ 0x7e, 0x67, 0xd9, 0xd6, 0x9d, 0x61, 0xc4, 0x47, 0x3b, 0x35, 0xff, 0xef,
+ 0x0b, 0xff, 0xdc, 0x40, 0x83, 0xda, 0x3a, 0xff, 0xa2, 0x7f, 0xb2, 0xe8,
+ 0x1e, 0x73, 0xaa, 0x11, 0x0b, 0xc4, 0x9b, 0xff, 0xb3, 0x79, 0x7c, 0xeb,
+ 0xb6, 0x04, 0x27, 0x5f, 0xdb, 0x3e, 0xf8, 0x63, 0xf3, 0xaf, 0xff, 0x47,
+ 0xbf, 0x89, 0x66, 0xfe, 0x9c, 0x0c, 0x9d, 0x50, 0x7f, 0xc8, 0x63, 0x7f,
+ 0x3f, 0xfc, 0xe2, 0x70, 0xeb, 0xde, 0xf9, 0x87, 0x57, 0xe7, 0x95, 0xf4,
+ 0xb6, 0xfe, 0xd2, 0x28, 0xb7, 0xf1, 0xd7, 0xff, 0xfe, 0xe6, 0x6c, 0x81,
+ 0xf7, 0xcf, 0xa3, 0x1d, 0x74, 0xf4, 0x7b, 0x47, 0x5f, 0xc3, 0x9a, 0xf8,
+ 0xd5, 0x51, 0xd5, 0xba, 0x33, 0x78, 0x5b, 0xb1, 0xba, 0xfb, 0xe6, 0xcd,
+ 0xa9, 0xce, 0xac, 0x3d, 0xd5, 0x0c, 0xec, 0xae, 0x75, 0xde, 0xc3, 0xaf,
+ 0xff, 0x2a, 0x46, 0x16, 0xe9, 0xd7, 0xf7, 0x60, 0xea, 0x83, 0xdf, 0x00,
+ 0xad, 0xfe, 0xea, 0x4c, 0xed, 0xd4, 0x8e, 0xbf, 0xd0, 0x3e, 0x75, 0xa7,
+ 0x8e, 0xbf, 0xec, 0x4c, 0x58, 0xe4, 0xee, 0x75, 0xfa, 0x3d, 0xaf, 0xc0,
+ 0x75, 0x2b, 0x29, 0xa9, 0xe3, 0x93, 0x48, 0x7a, 0x66, 0x26, 0x1e, 0x35,
+ 0xbf, 0xff, 0x74, 0x73, 0xdd, 0x4c, 0xdf, 0xd9, 0xb2, 0x34, 0x75, 0xff,
+ 0xce, 0x3d, 0x84, 0x0a, 0x6b, 0x24, 0x75, 0xe8, 0xff, 0xe9, 0xd5, 0x88,
+ 0xb3, 0x75, 0x51, 0x40, 0xbd, 0xf4, 0x38, 0x75, 0xe5, 0x4e, 0x95, 0x47,
+ 0x53, 0x9e, 0x0e, 0x87, 0x6f, 0xf0, 0xbb, 0x31, 0xec, 0x9c, 0xeb, 0x30,
+ 0xaa, 0x65, 0x6e, 0xc4, 0x64, 0x01, 0x84, 0x56, 0x46, 0x00, 0xd8, 0x46,
+ 0xee, 0xab, 0x34, 0x31, 0x39, 0x0a, 0xb5, 0x91, 0x76, 0x18, 0x7f, 0xb5,
+ 0x0c, 0x69, 0xfa, 0x8d, 0xd7, 0xd1, 0x87, 0x01, 0xbb, 0x6c, 0x86, 0xff,
+ 0xfb, 0x89, 0xbc, 0xb4, 0x9e, 0xec, 0x73, 0xd0, 0x75, 0xfb, 0x8d, 0x77,
+ 0x69, 0xa2, 0xae, 0xbd, 0xc8, 0x59, 0xd7, 0xfd, 0x26, 0x33, 0x8d, 0x77,
+ 0x69, 0xa2, 0x3c, 0xbf, 0xe8, 0x94, 0x72, 0x78, 0xe4, 0xe7, 0x5f, 0xfa,
+ 0x3c, 0x80, 0x54, 0xe4, 0xa7, 0x98, 0xeb, 0x30, 0x14, 0xd7, 0xb1, 0x3f,
+ 0x86, 0x6e, 0x36, 0x28, 0xba, 0x39, 0xbf, 0x71, 0xae, 0xed, 0x34, 0x58,
+ 0x37, 0x94, 0x89, 0xce, 0xbf, 0xff, 0x84, 0x0f, 0x3a, 0xf3, 0x6c, 0x1c,
+ 0xce, 0x4b, 0xec, 0x8e, 0xbf, 0x60, 0xe7, 0xb4, 0x75, 0xfe, 0xe3, 0xaf,
+ 0xef, 0x1f, 0x73, 0xac, 0xc6, 0x26, 0x14, 0xa1, 0x9b, 0x47, 0x5d, 0x83,
+ 0xe9, 0x2d, 0xfe, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x2c, 0xab, 0xf7, 0x1a,
+ 0xee, 0xd3, 0x45, 0xa7, 0x7f, 0xce, 0x1e, 0xbc, 0xdd, 0x45, 0x9d, 0x66,
+ 0x30, 0xfa, 0xd6, 0x67, 0x7e, 0x56, 0x8a, 0xbd, 0x59, 0x56, 0x55, 0xb3,
+ 0xaf, 0xf9, 0x55, 0xd4, 0x64, 0x2e, 0xed, 0x3a, 0xfc, 0xad, 0x15, 0x1a,
+ 0xc8, 0x3a, 0xff, 0x7d, 0x5e, 0x7b, 0x49, 0xa3, 0xac, 0x87, 0x52, 0xa8,
+ 0xf0, 0xf6, 0xcd, 0x2f, 0xff, 0xe4, 0xeb, 0x8f, 0xa5, 0x9c, 0xc8, 0x11,
+ 0xcf, 0x1d, 0x7e, 0xd8, 0xe1, 0xc5, 0x9d, 0x7c, 0xb8, 0xdf, 0x47, 0x54,
+ 0x91, 0x3f, 0x8a, 0xb3, 0x14, 0x5f, 0xbe, 0x73, 0x80, 0xe9, 0xd7, 0xe4,
+ 0x52, 0x05, 0xa7, 0x5b, 0x34, 0x7a, 0x1e, 0x2a, 0xbf, 0xfe, 0x16, 0xf5,
+ 0x3a, 0x9c, 0x89, 0x99, 0xce, 0x9d, 0x7f, 0xe5, 0xad, 0xe5, 0xb6, 0x0e,
+ 0xa7, 0x0e, 0xbf, 0x3e, 0xbd, 0x01, 0x3a, 0xa0, 0xf9, 0xc0, 0x83, 0x50,
+ 0x8d, 0x7e, 0xc2, 0xda, 0xfa, 0x3e, 0xc7, 0x4e, 0xbe, 0x6b, 0xbb, 0x4d,
+ 0x16, 0xe5, 0xff, 0xb3, 0x98, 0x3f, 0x3b, 0x9b, 0xb2, 0x75, 0xf8, 0x7f,
+ 0x7d, 0xf4, 0x75, 0x41, 0xf4, 0x3a, 0x05, 0x6e, 0x8d, 0x7e, 0x11, 0x6a,
+ 0x12, 0xb7, 0xf9, 0xc7, 0xf9, 0x86, 0x16, 0x75, 0xe5, 0x8a, 0x1d, 0x61,
+ 0x3a, 0xff, 0xba, 0x07, 0xd6, 0x60, 0xa8, 0x75, 0xfb, 0x4f, 0xbb, 0x84,
+ 0xeb, 0x20, 0x4f, 0x7b, 0xc6, 0xf5, 0x08, 0xae, 0xc1, 0xae, 0xb6, 0xdf,
+ 0xf4, 0x38, 0xf7, 0x30, 0x5a, 0x75, 0xfe, 0xf7, 0x92, 0x75, 0xc0, 0x9d,
+ 0x52, 0x3e, 0x6c, 0x34, 0xbf, 0xe8, 0x10, 0x2e, 0x35, 0xe4, 0x3a, 0xf8,
+ 0x31, 0x9c, 0x3a, 0xfd, 0xf3, 0x7d, 0x22, 0x87, 0x59, 0xe7, 0x3c, 0xbd,
+ 0xc8, 0x2f, 0xfe, 0x96, 0x75, 0x38, 0x1e, 0xc0, 0xb4, 0xeb, 0xfd, 0xbc,
+ 0xa0, 0x7d, 0x9f, 0x9d, 0x7d, 0xaf, 0xd3, 0xc7, 0x53, 0xa3, 0x03, 0x45,
+ 0x20, 0x42, 0xfa, 0x67, 0x7f, 0xf7, 0x93, 0xf8, 0x90, 0x7b, 0x02, 0xd3,
+ 0xa8, 0xeb, 0xc0, 0x7f, 0x1d, 0x70, 0x20, 0xea, 0x91, 0xb0, 0xf0, 0xdd,
+ 0x1d, 0x7d, 0xbb, 0x53, 0x87, 0x5e, 0x85, 0xb1, 0x88, 0x87, 0xdc, 0xe9,
+ 0x64, 0x3e, 0x0a, 0xa8, 0x4c, 0x65, 0x21, 0x95, 0x78, 0x7d, 0xb6, 0x75,
+ 0xff, 0x49, 0x8c, 0xe3, 0x5d, 0xda, 0x68, 0xa1, 0xe9, 0x0f, 0x8d, 0xc7,
+ 0xaf, 0xdf, 0xc3, 0x71, 0x67, 0x5f, 0x44, 0xd8, 0x13, 0xab, 0x87, 0x91,
+ 0xa2, 0x7b, 0xfe, 0xc8, 0x0f, 0x63, 0x6a, 0x26, 0x3a, 0xff, 0x7e, 0x9d,
+ 0xee, 0x7e, 0xe7, 0x52, 0xcf, 0xb7, 0xf3, 0xaa, 0x84, 0x59, 0x3c, 0x23,
+ 0xef, 0xfc, 0xe1, 0x80, 0xf5, 0x05, 0x16, 0x75, 0xff, 0xda, 0x81, 0x9b,
+ 0x07, 0xf7, 0xf6, 0x1d, 0x7f, 0xb4, 0x06, 0xe7, 0x86, 0x0e, 0xa5, 0xa2,
+ 0xbb, 0xa7, 0x7e, 0x42, 0xbf, 0xf8, 0x12, 0xeb, 0xf3, 0x7f, 0x42, 0x4e,
+ 0x75, 0xff, 0x44, 0xa3, 0x93, 0xc7, 0x27, 0x3a, 0xfc, 0x9e, 0xd3, 0xa1,
+ 0xd7, 0xfd, 0xcf, 0xf8, 0xe3, 0xec, 0xfc, 0xea, 0xfc, 0xf7, 0x80, 0x4b,
+ 0x7b, 0xef, 0x24, 0x75, 0xfd, 0xf7, 0xc0, 0x8c, 0x9c, 0xea, 0x91, 0xe6,
+ 0xcc, 0x3d, 0x7f, 0xf3, 0x46, 0x3c, 0x39, 0xb3, 0x39, 0x23, 0xaf, 0xf8,
+ 0x02, 0xa7, 0xde, 0xf4, 0x1a, 0x3a, 0xff, 0x08, 0xbf, 0xbe, 0xc3, 0x4e,
+ 0xbe, 0x1f, 0xe7, 0xfc, 0xea, 0xc3, 0xd6, 0x43, 0x2b, 0xfd, 0xaf, 0x9e,
+ 0xf8, 0x1c, 0x13, 0xad, 0xf9, 0xd6, 0x4d, 0xcf, 0x1f, 0x86, 0xd7, 0xe7,
+ 0xdf, 0x5e, 0x43, 0xaa, 0x13, 0xae, 0xc2, 0x34, 0x43, 0xec, 0x24, 0x85,
+ 0x9f, 0x45, 0x17, 0xe7, 0x02, 0x91, 0xf4, 0xeb, 0xf2, 0xab, 0x39, 0x1a,
+ 0x3a, 0xa6, 0x3d, 0x31, 0x29, 0xbf, 0xe7, 0xd4, 0x4d, 0xbc, 0xb3, 0x61,
+ 0xd7, 0xff, 0xe0, 0xf6, 0x3e, 0xb1, 0xe1, 0x7f, 0xf5, 0xa8, 0xfc, 0xab,
+ 0x83, 0x87, 0x5f, 0xa7, 0x89, 0xdf, 0x47, 0x56, 0x22, 0x59, 0x16, 0x5c,
+ 0x56, 0xef, 0xc0, 0x75, 0xfc, 0xff, 0xcc, 0x30, 0x13, 0xaa, 0x0f, 0x13,
+ 0xa2, 0xf6, 0x61, 0x58, 0x6c, 0x1b, 0x15, 0xb4, 0x35, 0x5e, 0x78, 0xab,
+ 0x39, 0xc4, 0x32, 0x25, 0x08, 0x00, 0xc3, 0xfb, 0x21, 0xfc, 0xa1, 0xb3,
+ 0x61, 0xc1, 0xbc, 0x25, 0x10, 0x86, 0x68, 0xd0, 0x79, 0x1a, 0xba, 0xe1,
+ 0x15, 0xd8, 0xc6, 0x9e, 0x1a, 0x9f, 0x98, 0x0a, 0x2e, 0xa1, 0x2f, 0xe9,
+ 0x43, 0xc0, 0x85, 0x66, 0xc2, 0x2d, 0xb8, 0x68, 0xfd, 0x71, 0xbf, 0x98,
+ 0x9e, 0x39, 0x25, 0x9d, 0x7f, 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x8b, 0xce,
+ 0xa1, 0xd2, 0x14, 0x49, 0xbc, 0x31, 0x81, 0x65, 0x2c, 0x37, 0x79, 0x50,
+ 0x1c, 0x8d, 0x99, 0x6a, 0x7d, 0x85, 0x50, 0xd6, 0x12, 0x9a, 0x8f, 0x17,
+ 0x61, 0x7d, 0xfe, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x29, 0x6b, 0xf7, 0x1a,
+ 0xee, 0xd3, 0x45, 0x85, 0x7f, 0xfe, 0x8c, 0x10, 0xc7, 0x63, 0x7f, 0x60,
+ 0xba, 0xce, 0xbf, 0x81, 0xc4, 0x9d, 0xd6, 0x75, 0x98, 0xc4, 0x58, 0xac,
+ 0xcf, 0x6d, 0x46, 0xff, 0x31, 0x9c, 0x6b, 0xbb, 0x4d, 0x16, 0x5d, 0xdc,
+ 0x50, 0xeb, 0xe6, 0x14, 0x55, 0x95, 0x83, 0xaf, 0x31, 0xf5, 0x67, 0x53,
+ 0x4f, 0x34, 0x05, 0xd4, 0x28, 0x86, 0xd3, 0x25, 0xbf, 0x3a, 0xe5, 0x27,
+ 0x3a, 0xe7, 0xe4, 0x8d, 0x4e, 0x08, 0xdf, 0xf3, 0xee, 0x39, 0xbf, 0xa1,
+ 0x43, 0xaf, 0xf4, 0xfb, 0xea, 0x03, 0xe4, 0x3a, 0xfd, 0x19, 0xb2, 0x34,
+ 0x75, 0xa1, 0xcf, 0x6d, 0x93, 0x4a, 0x74, 0x5d, 0x8c, 0x25, 0x2f, 0x9e,
+ 0x52, 0x09, 0xd7, 0xf3, 0xf2, 0x3c, 0xfd, 0x3a, 0xf3, 0x2c, 0xb2, 0x55,
+ 0xff, 0x44, 0xb7, 0xf7, 0x23, 0x37, 0x29, 0x82, 0xfe, 0xff, 0x80, 0xfb,
+ 0xe7, 0x93, 0x76, 0x4e, 0xba, 0x34, 0x75, 0x05, 0x30, 0x3e, 0x90, 0x8a,
+ 0x56, 0x92, 0x76, 0x1d, 0x5f, 0xc8, 0xfa, 0xff, 0x40, 0x3a, 0xff, 0xfe,
+ 0xea, 0x7b, 0xb9, 0xa1, 0xc5, 0x83, 0x5d, 0x79, 0x1d, 0x7f, 0xa2, 0x5e,
+ 0x7e, 0xb8, 0x4e, 0xac, 0x44, 0x57, 0x16, 0x6d, 0x23, 0xad, 0x23, 0xad,
+ 0x23, 0xaa, 0x0d, 0x82, 0x82, 0x08, 0x21, 0x7f, 0xfe, 0xf6, 0x91, 0xb8,
+ 0x3c, 0x81, 0xc0, 0xe2, 0x87, 0x5b, 0x73, 0xae, 0xd0, 0x0e, 0xac, 0x3f,
+ 0x9d, 0x29, 0x78, 0x46, 0xe4, 0x83, 0xaf, 0xe1, 0x85, 0x8c, 0x61, 0xd7,
+ 0x4a, 0x0e, 0xa0, 0x9e, 0x94, 0xc2, 0x80, 0x29, 0xbf, 0xff, 0xfe, 0xec,
+ 0x7b, 0x49, 0xad, 0x47, 0xba, 0x91, 0xcf, 0xd6, 0xf2, 0x97, 0x94, 0x3a,
+ 0xe4, 0xdc, 0xeb, 0xa1, 0x67, 0x5f, 0xff, 0xd2, 0x81, 0x04, 0xa5, 0x1e,
+ 0xee, 0x2f, 0xec, 0x7e, 0x75, 0xcd, 0x62, 0x17, 0x82, 0xa7, 0x4b, 0x0c,
+ 0x39, 0xb2, 0x32, 0x96, 0xa6, 0x72, 0x16, 0xee, 0xa4, 0x30, 0xa6, 0xd4,
+ 0x20, 0x3c, 0x61, 0xb1, 0xfb, 0x6c, 0x5b, 0xe8, 0xad, 0xff, 0xe6, 0x16,
+ 0xf2, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x28, 0xcb, 0xf6, 0xc8, 0xe4, 0x7e,
+ 0x75, 0xf8, 0x5f, 0xf8, 0xfa, 0x75, 0xff, 0xdb, 0xb5, 0x39, 0xdc, 0xc1,
+ 0x96, 0x8e, 0xb3, 0x10, 0x89, 0x4e, 0x94, 0xf8, 0xa2, 0xa4, 0xc9, 0xf9,
+ 0xe4, 0x3c, 0x16, 0x72, 0xf3, 0xd9, 0xfa, 0x87, 0x07, 0xa1, 0xd7, 0x7f,
+ 0xf3, 0x0f, 0x26, 0x33, 0x8d, 0x77, 0x69, 0xa2, 0x39, 0xbf, 0xfc, 0xc2,
+ 0xde, 0x4c, 0x67, 0x1a, 0xee, 0xd3, 0x44, 0xe5, 0x7f, 0x98, 0xce, 0x35,
+ 0xdd, 0xa6, 0x8b, 0x32, 0xff, 0xa5, 0xa7, 0x5b, 0x1d, 0xf7, 0xe7, 0x5f,
+ 0xf2, 0xae, 0x0e, 0x2e, 0x37, 0x85, 0x9d, 0x7f, 0xdf, 0xf2, 0x3d, 0xd7,
+ 0xde, 0x47, 0x5f, 0xec, 0xd7, 0x39, 0x9b, 0xe8, 0xeb, 0xfb, 0x8d, 0xeb,
+ 0xa2, 0xa4, 0xeb, 0xb7, 0x59, 0xd6, 0x61, 0x58, 0x47, 0x94, 0x1f, 0x48,
+ 0xe8, 0x06, 0x7b, 0x66, 0x17, 0xf9, 0x8c, 0xe3, 0x5d, 0xda, 0x68, 0xb7,
+ 0x6f, 0xe1, 0x76, 0x39, 0x3f, 0x4e, 0xbc, 0x9b, 0xfe, 0x75, 0xfb, 0x8d,
+ 0x77, 0x69, 0xa2, 0x90, 0xbf, 0xf6, 0x75, 0x36, 0x77, 0x30, 0x5a, 0x75,
+ 0xe7, 0x93, 0x18, 0x7e, 0x1a, 0x33, 0xb3, 0x0d, 0x47, 0x77, 0x0b, 0x97,
+ 0x08, 0xdb, 0xff, 0x98, 0x79, 0x31, 0x9c, 0x6b, 0xbb, 0x4d, 0x12, 0x95,
+ 0x4e, 0xb8, 0x4d, 0x32, 0x8a, 0xd5, 0xdc, 0xff, 0xf8, 0xcb, 0x45, 0x63,
+ 0xd1, 0x96, 0xed, 0x1e, 0x5f, 0xe9, 0x20, 0xfb, 0x10, 0x27, 0x5e, 0xd0,
+ 0x16, 0x75, 0x98, 0xdc, 0xf3, 0x10, 0xc2, 0xf0, 0xbc, 0x8e, 0xbf, 0xf3,
+ 0xc9, 0x8c, 0xe3, 0x5d, 0xda, 0x68, 0x9d, 0xae, 0x9d, 0x5c, 0xeb, 0xff,
+ 0xf2, 0x04, 0x0b, 0x8d, 0xa7, 0x08, 0xc0, 0xe3, 0x4e, 0xbf, 0xe8, 0x94,
+ 0x72, 0x78, 0xe4, 0xe7, 0x59, 0x8c, 0x4c, 0x2d, 0x63, 0x5d, 0x4a, 0x71,
+ 0xa1, 0x54, 0xbf, 0xfe, 0x63, 0xee, 0xdb, 0x8f, 0xf9, 0xe8, 0x14, 0xfc,
+ 0xeb, 0xff, 0x9d, 0x7d, 0xc6, 0xbf, 0x63, 0xec, 0x8e, 0xbc, 0x81, 0x73,
+ 0xaf, 0xfe, 0x1c, 0xeb, 0xcf, 0x9a, 0x17, 0xdc, 0xeb, 0xb6, 0xd8, 0x0a,
+ 0x28, 0x3a, 0x89, 0xa1, 0xaa, 0x92, 0xab, 0x75, 0xc6, 0x69, 0xa4, 0xfd,
+ 0xb8, 0x7a, 0x5f, 0xff, 0xc1, 0x7f, 0x31, 0x9a, 0x81, 0xdf, 0xfd, 0x6a,
+ 0x3f, 0x3a, 0xfd, 0xc6, 0xbb, 0xb4, 0xd1, 0x16, 0x5f, 0xf9, 0xe4, 0xc6,
+ 0x71, 0xae, 0xed, 0x34, 0x4b, 0xb7, 0xff, 0xf6, 0x07, 0xb1, 0xf5, 0x8f,
+ 0x0b, 0xff, 0xad, 0x47, 0xe5, 0x59, 0x8c, 0x46, 0xda, 0xcc, 0xf6, 0xd2,
+ 0xaf, 0xff, 0x30, 0xb7, 0x93, 0x19, 0xc6, 0xbb, 0xb4, 0xd1, 0x31, 0x5f,
+ 0xb8, 0xd7, 0x76, 0x9a, 0x2a, 0x9b, 0x61, 0xd5, 0x87, 0x84, 0xa1, 0x9d,
+ 0xff, 0xff, 0xee, 0x3f, 0x77, 0x96, 0x79, 0x8e, 0xbe, 0xb8, 0x8c, 0xfb,
+ 0xa9, 0xc9, 0x1d, 0x4c, 0x22, 0x71, 0xc8, 0xaf, 0xff, 0x30, 0xb7, 0x93,
+ 0x19, 0xc6, 0xbb, 0xb4, 0xd1, 0x3a, 0x5f, 0xe4, 0x7e, 0x44, 0x9f, 0x61,
+ 0xd7, 0xe9, 0xa2, 0x68, 0xd1, 0xd7, 0xf3, 0x38, 0x9b, 0x30, 0x4e, 0xa4,
+ 0x3d, 0x5d, 0x14, 0x5e, 0x4e, 0xc1, 0xcc, 0x1a, 0x1b, 0xff, 0x81, 0xaf,
+ 0x46, 0xec, 0x02, 0x64, 0x59, 0xd4, 0xb3, 0xf2, 0xe9, 0x5d, 0xff, 0x9e,
+ 0x4c, 0x67, 0x1a, 0xee, 0xd3, 0x44, 0xef, 0x7e, 0xf0, 0x1d, 0x68, 0x55,
+ 0xff, 0x86, 0x3d, 0x9a, 0xcc, 0xde, 0x47, 0x50, 0x53, 0xe8, 0xc8, 0xc6,
+ 0x96, 0x44, 0xe9, 0x5e, 0x26, 0xbf, 0xa1, 0x8f, 0xc7, 0x02, 0x75, 0x30,
+ 0x7f, 0x82, 0x9f, 0x7f, 0xf9, 0x85, 0xbc, 0x98, 0xce, 0x35, 0xdd, 0xa6,
+ 0x8a, 0x16, 0xff, 0xff, 0xf7, 0x40, 0xb5, 0xbc, 0x98, 0x6f, 0x41, 0xe8,
+ 0x1c, 0x9d, 0x40, 0x44, 0xc7, 0x5f, 0x81, 0xbf, 0x91, 0xa7, 0x5f, 0xb3,
+ 0xfc, 0x71, 0x3a, 0xf4, 0x7e, 0xc4, 0xe7, 0x9a, 0x25, 0x14, 0x88, 0xfd,
+ 0x18, 0x64, 0x5f, 0xfe, 0x61, 0x6f, 0x26, 0x33, 0x8d, 0x77, 0x69, 0xa2,
+ 0x92, 0xbf, 0xff, 0xd9, 0xa6, 0x3e, 0xe4, 0xdd, 0x75, 0xfb, 0xb1, 0xe0,
+ 0x2c, 0xea, 0x85, 0xfd, 0xb9, 0xe3, 0x38, 0x91, 0xcb, 0x63, 0x35, 0xe1,
+ 0x1a, 0xe5, 0x5d, 0xfe, 0x45, 0xe8, 0xd5, 0x00, 0x4d, 0xb6, 0xaf, 0x7f,
+ 0x98, 0xce, 0x35, 0xdd, 0xa6, 0x88, 0x92, 0xff, 0xf3, 0x0b, 0x79, 0x31,
+ 0x9c, 0x6b, 0xbb, 0x4d, 0x12, 0xf5, 0xf7, 0x01, 0xed, 0x1d, 0x7e, 0xe7,
+ 0xeb, 0x4d, 0x1d, 0x7a, 0x07, 0x73, 0xaf, 0xde, 0xfa, 0xb1, 0x83, 0xac,
+ 0x9d, 0x3c, 0x31, 0x1b, 0xbf, 0xfd, 0xdd, 0x90, 0x3f, 0xab, 0xe0, 0x73,
+ 0x9b, 0x9d, 0x74, 0x78, 0xeb, 0xff, 0xc0, 0x0a, 0x73, 0xec, 0xdb, 0x40,
+ 0x71, 0x98, 0xea, 0x92, 0x36, 0x90, 0x9b, 0xf4, 0xfd, 0x0a, 0xdf, 0xfc,
+ 0xf3, 0x6a, 0x36, 0x3f, 0x63, 0x79, 0x8e, 0xbf, 0x64, 0xf9, 0xa5, 0x9d,
+ 0x7f, 0xf4, 0xdf, 0x3e, 0x8c, 0x6c, 0x7d, 0x91, 0x31, 0xd4, 0x75, 0xfd,
+ 0x34, 0x9f, 0xcf, 0xb0, 0xea, 0x84, 0x42, 0xe2, 0x63, 0x85, 0x5d, 0xc8,
+ 0x3a, 0x82, 0xab, 0x65, 0x08, 0xa6, 0x8d, 0x17, 0x87, 0xa2, 0x8f, 0xb2,
+ 0x15, 0x9b, 0x45, 0xb7, 0x83, 0x82, 0x75, 0xc1, 0xdc, 0xeb, 0xfe, 0x47,
+ 0x10, 0x7a, 0x68, 0x50, 0xeb, 0xff, 0xe4, 0xe7, 0xce, 0xc2, 0x7b, 0x40,
+ 0x68, 0x20, 0xeb, 0xe4, 0x9f, 0xf5, 0x73, 0xaf, 0x9a, 0xee, 0xd3, 0x45,
+ 0x2f, 0x7c, 0x3e, 0x8e, 0x1d, 0x7f, 0xd9, 0xc5, 0x7c, 0x0e, 0x73, 0x73,
+ 0xa9, 0x0f, 0x6f, 0x61, 0x05, 0x28, 0x99, 0x0c, 0xca, 0x1c, 0x26, 0xec,
+ 0x22, 0x2f, 0xc3, 0xe9, 0xf1, 0x93, 0xaf, 0xfd, 0x03, 0x1d, 0xf8, 0x01,
+ 0x03, 0x4e, 0xbc, 0x07, 0xd1, 0xd7, 0xe8, 0xfd, 0xf7, 0xd1, 0xd7, 0x85,
+ 0x3f, 0x3a, 0xf6, 0x7b, 0x47, 0x54, 0x1b, 0x6d, 0x0d, 0xd0, 0x51, 0xaf,
+ 0x31, 0xf7, 0xe3, 0x7e, 0x5e, 0xbf, 0x2b, 0xb8, 0x87, 0x68, 0xeb, 0xfe,
+ 0xff, 0x5c, 0x8d, 0xe4, 0x8b, 0x3a, 0xf7, 0x9f, 0x61, 0xd7, 0xfc, 0xf3,
+ 0xfc, 0x9c, 0x13, 0x42, 0xb9, 0xd5, 0x08, 0x97, 0x73, 0xa0, 0x0e, 0xdf,
+ 0xf2, 0x6a, 0x64, 0x1f, 0x47, 0xe7, 0x54, 0x8f, 0x99, 0x65, 0xd7, 0x38,
+ 0x9d, 0x7f, 0xd1, 0xff, 0xce, 0xc2, 0xdc, 0x4e, 0xb7, 0x37, 0x3c, 0xdd,
+ 0x82, 0x95, 0x09, 0xe1, 0xe4, 0x65, 0x28, 0xdf, 0x7b, 0x90, 0xb3, 0xaf,
+ 0xe8, 0x19, 0xbc, 0x8a, 0x1d, 0x7f, 0xd2, 0xce, 0x4d, 0x83, 0x0b, 0x3a,
+ 0xfd, 0xfc, 0x37, 0x16, 0x75, 0x21, 0xef, 0x70, 0xde, 0xe9, 0x61, 0xd7,
+ 0xa3, 0xfd, 0x1d, 0x50, 0x7a, 0x41, 0x21, 0x64, 0x56, 0xfd, 0xd0, 0x29,
+ 0x82, 0x75, 0xff, 0x47, 0x74, 0xfe, 0x8e, 0x6d, 0x1d, 0x7f, 0xe5, 0xb8,
+ 0x7e, 0xcd, 0x28, 0x1d, 0xce, 0xa0, 0x9f, 0xda, 0x1d, 0x5f, 0x73, 0xff,
+ 0xbb, 0x0e, 0xbc, 0x8c, 0xf8, 0xea, 0xe9, 0xe1, 0xe8, 0x9e, 0x82, 0x99,
+ 0x47, 0x61, 0x45, 0xe6, 0x4b, 0xfe, 0xfd, 0x3b, 0x9c, 0x79, 0xb4, 0x75,
+ 0xff, 0xfa, 0x24, 0x31, 0x3f, 0xd9, 0xb5, 0xdc, 0xda, 0xe7, 0xe7, 0x5f,
+ 0xdf, 0x17, 0x9e, 0x7f, 0x1d, 0x66, 0x9d, 0x76, 0xfa, 0xc3, 0x7c, 0xe5,
+ 0xd5, 0xba, 0x3f, 0xd6, 0x72, 0xf0, 0x9a, 0xbf, 0xd8, 0xcc, 0x93, 0x40,
+ 0x59, 0xd7, 0x6c, 0xd1, 0xd7, 0xec, 0x9f, 0x3b, 0xa3, 0xaa, 0x0d, 0xf8,
+ 0x8c, 0x5e, 0xce, 0x68, 0xea, 0x69, 0xba, 0xd8, 0x3f, 0x7f, 0xdf, 0xc7,
+ 0xff, 0x76, 0x40, 0xed, 0x1d, 0x50, 0x98, 0x7e, 0x42, 0xb1, 0x08, 0xef,
+ 0xff, 0xfe, 0xec, 0x73, 0x76, 0xa6, 0xff, 0x14, 0x7f, 0x9a, 0xeb, 0xb6,
+ 0x04, 0x27, 0x5f, 0x78, 0x51, 0x67, 0x5f, 0xe1, 0x87, 0x1f, 0x60, 0x9d,
+ 0x7f, 0xba, 0xf3, 0x27, 0x22, 0x73, 0xae, 0xc5, 0x9d, 0x41, 0x4c, 0x37,
+ 0x1d, 0xd6, 0x40, 0xe5, 0xdb, 0x0c, 0xef, 0xdb, 0x48, 0xb8, 0xd1, 0xd7,
+ 0xe7, 0xd9, 0x9c, 0xd1, 0xd4, 0x13, 0xd1, 0x59, 0x4d, 0xfb, 0xae, 0x28,
+ 0xb3, 0xaf, 0x94, 0x9b, 0x50, 0x75, 0xfe, 0x7f, 0xf5, 0x1d, 0x8d, 0x1d,
+ 0x50, 0x89, 0xcc, 0x22, 0x42, 0x51, 0x23, 0xbb, 0xf6, 0x9d, 0x6d, 0x1d,
+ 0x72, 0x29, 0xa3, 0x4e, 0x01, 0x7b, 0xdf, 0xbb, 0x4e, 0xbf, 0xff, 0x20,
+ 0x73, 0x63, 0xf2, 0x6f, 0xb2, 0x7f, 0x3a, 0xce, 0xa8, 0x3f, 0x4e, 0x0e,
+ 0x59, 0x88, 0x66, 0xed, 0xce, 0xeb, 0x21, 0xa0, 0x8b, 0xe4, 0x6b, 0x3b,
+ 0xa2, 0xa4, 0x3f, 0xe6, 0x94, 0x05, 0xc3, 0x45, 0x8d, 0xf6, 0x1b, 0xaf,
+ 0x1a, 0xbf, 0xf1, 0x9a, 0x8c, 0x68, 0x9a, 0x8d, 0x03, 0xd1, 0x9c, 0x6d,
+ 0xb0, 0x7d, 0x85, 0x0d, 0xfe, 0x63, 0x38, 0xd7, 0x76, 0x9a, 0x29, 0xcb,
+ 0xff, 0x27, 0x1f, 0x5d, 0xcc, 0x16, 0x9d, 0x7e, 0x5f, 0x39, 0x9a, 0x3a,
+ 0xff, 0xfd, 0xd0, 0x7b, 0x91, 0xed, 0x63, 0x75, 0x1c, 0x69, 0xd7, 0xf9,
+ 0x16, 0x18, 0xd0, 0x04, 0xeb, 0xfb, 0x3d, 0xbc, 0xa1, 0x93, 0xaf, 0xfe,
+ 0x51, 0x37, 0xd0, 0xe0, 0x7a, 0xec, 0x9d, 0x7f, 0xec, 0xec, 0x73, 0x18,
+ 0x65, 0x96, 0x4a, 0xb9, 0x19, 0x3a, 0xe9, 0xd8, 0x0a, 0x76, 0x58, 0x76,
+ 0xd2, 0x7e, 0xaa, 0x89, 0x8f, 0x8b, 0xb6, 0xd1, 0x76, 0x90, 0x6f, 0xdc,
+ 0x6b, 0xbb, 0x4d, 0x15, 0xe5, 0xff, 0xfd, 0x81, 0xec, 0x7d, 0x63, 0xc2,
+ 0xff, 0xeb, 0x51, 0xf9, 0x56, 0x63, 0x11, 0x23, 0xb6, 0x67, 0x7f, 0xf3,
+ 0x0f, 0x26, 0x33, 0x8d, 0x77, 0x69, 0xa2, 0x47, 0xbc, 0xdc, 0x59, 0xd7,
+ 0x93, 0xf8, 0x3a, 0xf3, 0x71, 0x65, 0x30, 0x5d, 0xdf, 0xb8, 0xd7, 0x76,
+ 0x9a, 0x24, 0x8b, 0xff, 0xfa, 0x13, 0x89, 0xb5, 0x03, 0x3c, 0x79, 0x3a,
+ 0xf3, 0x9d, 0x74, 0x98, 0x84, 0x5c, 0xe1, 0x5f, 0x4c, 0xef, 0xd9, 0xd6,
+ 0x31, 0x67, 0x59, 0x88, 0x4d, 0x45, 0xe1, 0xdf, 0xe3, 0xbb, 0xff, 0x98,
+ 0x79, 0x31, 0x9c, 0x6b, 0xbb, 0x4d, 0x12, 0x55, 0xfb, 0x8d, 0x77, 0x69,
+ 0xa2, 0xf1, 0xbf, 0xe9, 0x31, 0x9c, 0x6b, 0xbb, 0x4d, 0x12, 0x6d, 0x98,
+ 0xc3, 0xf8, 0x73, 0x3b, 0x99, 0xe9, 0xd7, 0xe4, 0xff, 0x58, 0x27, 0x5f,
+ 0xff, 0x01, 0xf7, 0xcc, 0x51, 0x47, 0x96, 0x6f, 0xe3, 0xaa, 0x47, 0xef,
+ 0xa2, 0x6b, 0xdf, 0x46, 0x73, 0xae, 0xe7, 0x8e, 0xbd, 0x30, 0xce, 0x75,
+ 0x84, 0xeb, 0xbe, 0xfd, 0x3a, 0xbf, 0x35, 0x3f, 0x43, 0xee, 0xdb, 0x62,
+ 0x13, 0x4e, 0xc8, 0x47, 0x74, 0x89, 0xc7, 0xb4, 0x2d, 0xf5, 0x1a, 0xa1,
+ 0xba, 0x3f, 0x9c, 0xfe, 0x55, 0x88, 0x58, 0x63, 0x3c, 0x48, 0xfc, 0x66,
+ 0x8c, 0x55, 0x65, 0x9d, 0x8e, 0x8b, 0xc7, 0x60, 0x86, 0x4f, 0xd8, 0xdd,
+ 0x6a, 0x25, 0xfe, 0x10, 0x4f, 0x29, 0x1a, 0x53, 0xae, 0xe1, 0x9d, 0x4a,
+ 0xcc, 0x46, 0xc3, 0x29, 0x38, 0xdc, 0xdb, 0xd4, 0xdd, 0xde, 0xb2, 0xe3,
+ 0x4a, 0x4b, 0xea, 0xbc, 0xa2, 0x39, 0xad, 0x86, 0x3f, 0x2d, 0x09, 0x92,
+ 0xf3, 0x6c, 0x87, 0xed, 0x2a, 0x31, 0xed, 0x94, 0x17, 0xf3, 0xe6, 0xaa,
+ 0x98, 0xf8, 0xc6, 0xb2, 0xb6, 0xd5, 0x6e, 0x23, 0xeb, 0xd4, 0xa9, 0x05,
+ 0xaf, 0xeb, 0xd9, 0x4a, 0xc8, 0x66, 0x72, 0x5f, 0x6e, 0x5c, 0x3f, 0xda,
+ 0x41, 0x46, 0xd5, 0x75, 0xd5, 0x40,
};
-static const unsigned kPreloadedHSTSBits = 213993;
+static const unsigned kPreloadedHSTSBits = 265770;
-static const unsigned kHSTSRootPosition = 213387;
+static const unsigned kHSTSRootPosition = 265157;
#endif // NET_HTTP_TRANSPORT_SECURITY_STATE_STATIC_H_
diff --git a/chromium/net/http/transport_security_state_static.json b/chromium/net/http/transport_security_state_static.json
index 841a9ff148c..4bff1eab791 100644
--- a/chromium/net/http/transport_security_state_static.json
+++ b/chromium/net/http/transport_security_state_static.json
@@ -13,6 +13,8 @@
// static_spki_hashes: (list of strings) the set of allowed SPKIs hashes
// bad_static_spki_hashes: (optional list of strings) the set of forbidden
// SPKIs hashes
+// report_uri: (optional string) the URI to send violation reports to;
+// reports will be in the format defined in RFC 7469
//
// For a given pinset, a certificate is accepted if at least one of the
// "static_spki_hashes" SPKIs is found in the chain and none of the
@@ -23,6 +25,9 @@
// name: (string) the DNS name of the host in question
// include_subdomains: (optional bool) whether subdomains of |name| are also
// covered
+// include_subdomains_for_pinning: (optional bool) whether subdomains
+// of |name| are also covered for pinning. |include_subdomains|
+// implies this.
// mode: (optional string) "force-https" iff covered names should require
// HTTPS
// pins: (optional string) the |name| member of an object in |pinsets|
@@ -41,7 +46,8 @@
"GoogleBackup2048",
"GoogleG2",
"GeoTrustGlobal"
- ]
+ ],
+ "report_uri": "http://clients3.google.com/cert_upload_json"
},
{
"name": "tor",
@@ -150,7 +156,8 @@
"ThawtePrimaryRootCA_G2",
"ThawtePrimaryRootCA_G3",
"ThawtePrimaryRootCA"
- ]
+ ],
+ "report_uri": "https://log.getdropbox.com/hpkp"
},
{
"name": "facebook",
@@ -212,6 +219,9 @@
{ "name": "passwords.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "myaccount.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "contributor.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "fi.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "xn--7xa.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "pixel.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
// Other Google-related domains that must use HTTPS.
{ "name": "google", "include_subdomains": true, "mode": "force-https", "pins": "google" },
@@ -236,6 +246,8 @@
{ "name": "translate.googleapis.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "gvt2.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "gvt3.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "withyoutube.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "withgoogle.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "webfilings.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "webfilings-mirror-hrd.appspot.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
@@ -282,6 +294,8 @@
{ "name": "g.co", "include_subdomains": true, "pins": "google" },
{ "name": "googletagmanager.com", "include_subdomains": true, "pins": "google" },
{ "name": "googletagservices.com", "include_subdomains": true, "pins": "google" },
+ { "name": "ggpht.com", "include_subdomains": true, "pins": "google" },
+ { "name": "blogspot.com", "include_subdomains": true, "pins": "google" },
{ "name": "google.ac", "include_subdomains": true, "pins": "google" },
{ "name": "google.ad", "include_subdomains": true, "pins": "google" },
{ "name": "google.ae", "include_subdomains": true, "pins": "google" },
@@ -825,8 +839,10 @@
{ "name": "z.ai", "include_subdomains": true, "mode": "force-https" },
{ "name": "wildbee.org", "include_subdomains": true, "mode": "force-https" },
{ "name": "portal.tirol.gv.at", "include_subdomains": true, "mode": "force-https" },
- { "name": "dropbox.com", "mode": "force-https", "pins": "dropbox" },
+ { "name": "dropbox.com", "mode": "force-https", "include_subdomains_for_pinning": true, "pins": "dropbox" },
{ "name": "www.dropbox.com", "include_subdomains": true, "mode": "force-https", "pins": "dropbox" },
+ { "name": "dropboxstatic.com", "include_subdomains_for_pinning": true, "pins": "dropbox" },
+ { "name": "dropboxusercontent.com", "include_subdomains_for_pinning": true, "pins": "dropbox" },
{ "name": "code-poets.co.uk", "include_subdomains": true, "mode": "force-https" },
{ "name": "jackyyf.com", "mode": "force-https" },
{ "name": "flynn.io", "include_subdomains": true, "mode": "force-https" },
@@ -1198,7 +1214,6 @@
{ "name": "digitaldaddy.net", "include_subdomains": true, "mode": "force-https" },
{ "name": "elnutricionista.es", "include_subdomains": true, "mode": "force-https" },
{ "name": "fronteers.nl", "include_subdomains": true, "mode": "force-https" },
- { "name": "getssl.uz", "include_subdomains": true, "mode": "force-https" },
{ "name": "gunnarhafdal.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "heijblok.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "kdex.de", "include_subdomains": true, "mode": "force-https" },
@@ -1257,6 +1272,7 @@
{ "name": "wepay.in.th", "include_subdomains": true, "mode": "force-https" },
{ "name": "zixiao.wang", "include_subdomains": true, "mode": "force-https" },
+
{ "name": "at.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
{ "name": "au.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
{ "name": "az.search.yahoo.com", "include_subdomains": false, "mode": "force-https" },
@@ -1621,6 +1637,7 @@
{ "name": "webtrh.cz", "include_subdomains": true, "mode": "force-https" },
{ "name": "yetii.net", "include_subdomains": true, "mode": "force-https" },
{ "name": "login.ubuntu.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pay.ubuntu.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "login.launchpad.net", "include_subdomains": true, "mode": "force-https" },
{ "name": "302.nyc", "include_subdomains": true, "mode": "force-https" },
{ "name": "biathloncup.ru", "include_subdomains": true, "mode": "force-https" },
@@ -1798,7 +1815,7 @@
{ "name": "gaytorrent.ru", "include_subdomains": true, "mode": "force-https" },
{ "name": "getable.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "gpsfix.cz", "include_subdomains": true, "mode": "force-https" },
- { "name": "guidetoiceland.is", "include_subdomains": true, "mode": "force-https" },
+ { "name": "guidetoiceland.is", "include_subdomains": false, "mode": "force-https" },
{ "name": "happylifestyle.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "heppler.net", "include_subdomains": true, "mode": "force-https" },
{ "name": "httpswatch.com", "include_subdomains": true, "mode": "force-https" },
@@ -1819,7 +1836,6 @@
{ "name": "narodniki.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "netrider.net.au", "include_subdomains": true, "mode": "force-https" },
{ "name": "niloxy.com", "include_subdomains": true, "mode": "force-https" },
- { "name": "noobs-r-us.co.uk", "include_subdomains": true, "mode": "force-https" },
{ "name": "nowhere.dk", "include_subdomains": true, "mode": "force-https" },
{ "name": "perfectionis.me", "include_subdomains": true, "mode": "force-https" },
{ "name": "phryanjr.com", "include_subdomains": true, "mode": "force-https" },
@@ -2190,7 +2206,6 @@
{ "name": "301.website", "include_subdomains": true, "mode": "force-https" },
{ "name": "alza.cz", "include_subdomains": true, "mode": "force-https" },
{ "name": "armytricka.cz", "include_subdomains": true, "mode": "force-https" },
- { "name": "astaxi.net", "include_subdomains": true, "mode": "force-https" },
{ "name": "bradkovach.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "crypto.graphics", "include_subdomains": true, "mode": "force-https" },
{ "name": "cryptography.io", "include_subdomains": true, "mode": "force-https" },
@@ -2222,7 +2237,6 @@
{ "name": "lapetition.be", "include_subdomains": true, "mode": "force-https" },
{ "name": "maartenvandekamp.nl", "include_subdomains": true, "mode": "force-https" },
{ "name": "mcard.vn", "include_subdomains": true, "mode": "force-https" },
- { "name": "mccrypto.de", "include_subdomains": true, "mode": "force-https" },
{ "name": "mcnext.net", "include_subdomains": true, "mode": "force-https" },
{ "name": "micropple.net", "include_subdomains": true, "mode": "force-https" },
{ "name": "munki.org", "include_subdomains": true, "mode": "force-https" },
@@ -2363,7 +2377,6 @@
{ "name": "keeley.gq", "include_subdomains": true, "mode": "force-https" },
{ "name": "keeley.ml", "include_subdomains": true, "mode": "force-https" },
{ "name": "keybase.io", "include_subdomains": true, "mode": "force-https" },
- { "name": "keycom.co.uk", "include_subdomains": true, "mode": "force-https" },
{ "name": "kinganywhere.eu", "include_subdomains": true, "mode": "force-https" },
{ "name": "ks-watch.de", "include_subdomains": true, "mode": "force-https" },
{ "name": "leakedminecraft.net", "include_subdomains": true, "mode": "force-https" },
@@ -2433,7 +2446,7 @@
{ "name": "blablacar.rs", "include_subdomains": true, "mode": "force-https" },
{ "name": "blablacar.ru", "include_subdomains": true, "mode": "force-https" },
{ "name": "canhazip.com", "include_subdomains": true, "mode": "force-https" },
- { "name": "carbonmade.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "carbonmade.com", "include_subdomains": false, "mode": "force-https" },
{ "name": "collinmbarrett.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "coloradocomputernetworking.net", "include_subdomains": true, "mode": "force-https" },
{ "name": "copperhead.co", "include_subdomains": true, "mode": "force-https" },
@@ -2447,7 +2460,6 @@
{ "name": "ethercalc.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "ethercalc.org", "include_subdomains": true, "mode": "force-https" },
{ "name": "fluxfingers.net", "include_subdomains": true, "mode": "force-https" },
- { "name": "getbambu.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "haber1903.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "initrd.net", "include_subdomains": true, "mode": "force-https" },
{ "name": "integromat.com", "include_subdomains": true, "mode": "force-https" },
@@ -2520,7 +2532,6 @@
{ "name": "fidelapp.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "floweslawncare.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "foxelbox.com", "include_subdomains": true, "mode": "force-https" },
- { "name": "fsma.pl", "include_subdomains": true, "mode": "force-https" },
{ "name": "getcolor.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "getsello.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "gheorghesarcov.ga", "include_subdomains": true, "mode": "force-https" },
@@ -2770,7 +2781,6 @@
{ "name": "patechmasters.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "payments-reference.org", "include_subdomains": true, "mode": "force-https" },
{ "name": "pbprint.ru", "include_subdomains": true, "mode": "force-https" },
- { "name": "phcorner.net", "include_subdomains": true, "mode": "force-https" },
{ "name": "pieterhordijk.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "poedgirl.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "poiema.com.sg", "include_subdomains": true, "mode": "force-https" },
@@ -2913,7 +2923,6 @@
{ "name": "cobalt.io", "include_subdomains": true, "mode": "force-https" },
{ "name": "dealbanana.it", "include_subdomains": true, "mode": "force-https" },
{ "name": "cydia-search.io", "include_subdomains": true, "mode": "force-https" },
- { "name": "delbart.se", "include_subdomains": true, "mode": "force-https" },
{ "name": "dotsiam.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "clevertarget.ru", "include_subdomains": true, "mode": "force-https" },
{ "name": "connext.de", "include_subdomains": true, "mode": "force-https" },
@@ -3122,7 +3131,728 @@
{ "name": "ccblog.de", "include_subdomains": true, "mode": "force-https" },
{ "name": "smiatek.name", "include_subdomains": true, "mode": "force-https" },
{ "name": "korni22.org", "include_subdomains": true, "mode": "force-https" },
- { "name": "student.andover.edu", "include_subdomains": true, "mode": "force-https" }
+ { "name": "student.andover.edu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "0.me.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "agilebits.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "alenan.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "amisharingstuff.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "amunoz.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "appuro.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "askfit.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "axado.com.br", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bebesurdoue.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "burnworks.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "canadalife.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "chaosdorf.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cheerflow.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "chrisbrown.id.au", "include_subdomains": true, "mode": "force-https" },
+ { "name": "chromebooksforwork.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cloudmigrator365.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cloudpagesforwork.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "clu-in.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cmc-versand.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cnlic.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cocoaheads.at", "include_subdomains": true, "mode": "force-https" },
+ { "name": "colorlib.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "corruption-mc.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "corruption-rsps.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "corruption-server.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cthulhuden.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dateno1.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "democracy.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "democracychronicles.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "demuzere.be", "include_subdomains": true, "mode": "force-https" },
+ { "name": "deviltracks.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dietrich.cx", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dissimulo.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dlscomputers.com.au", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dogoodbehappyllc.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dreid.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "e-deca2.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "elitehosting.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "empowerdb.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "endlesshorizon.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "entrepreneur.or.id", "include_subdomains": true, "mode": "force-https" },
+ { "name": "eol34.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "eroticen.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "eucl3d.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "firmapi.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "formationsfactory.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "freeweibo.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "funchestra.at", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gamenected.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gamenected.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "getsport.mobi", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ghostblog.info", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gmdu.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "grafitec.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "greatfire.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "greenroach.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hablemosdetecnologia.com.ve", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hardh.at", "include_subdomains": true, "mode": "force-https" },
+ { "name": "haveeruexaminer.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "helloacm.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hurricanelabs.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hyper-text.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "idndx.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "im-c-shop.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "inbitcoin.it", "include_subdomains": true, "mode": "force-https" },
+ { "name": "inspiroinc.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "instant-hack.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "iraqidinar.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "itsagadget.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ivancacic.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "j0s.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jamesmaurer.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jinbo123.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "joshstroup.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "justyy.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kasko.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kawaii.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kazandaemon.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kbcequitas.hu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "keskeces.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lehighmathcircle.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lenzw.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "leon-jaekel.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "linuxcommand.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lognot.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "maclemon.at", "include_subdomains": true, "mode": "force-https" },
+ { "name": "maternalsafety.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "max-moeglich.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mclab.su", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mdek.at", "include_subdomains": true, "mode": "force-https" },
+ { "name": "meddelare.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "medexpress.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mediawiki.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mikaela.info", "include_subdomains": true, "mode": "force-https" },
+ { "name": "milahendri.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "moniquedekermadec.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "msebera.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mypagella.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "necesitodinero.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "obermeiers.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ollning.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "omacostudio.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ourbank.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "paysera.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "petersmark.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "phryneas.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pinesandneedles.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pmnts.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "qingxuan.info", "include_subdomains": true, "mode": "force-https" },
+ { "name": "raah.co", "include_subdomains": true, "mode": "force-https" },
+ { "name": "recon-networks.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "renlong.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "reucon.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ristioja.ee", "include_subdomains": true, "mode": "force-https" },
+ { "name": "roberthurlbut.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rugstorene.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "shadowkitsune.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "shaundanielz.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "shellvatore.us", "include_subdomains": true, "mode": "force-https" },
+ { "name": "shipcloud.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "simplexsupport.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "slainvet.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "smartlocksmith.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "social-media-strategies.it", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sparklingsparklers.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sportifik.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tanzhijun.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tcao.info", "include_subdomains": true, "mode": "force-https" },
+ { "name": "teamblueridge.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tecart-cloud.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tecart-system.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tecartcrm.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "techandtux.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tehrabbitt.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thehiddenbay.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ticketmates.com.au", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tinyvpn.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tinyvpn.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tls1914.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "topnewstoday.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "totalcarcheck.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "toxme.se", "include_subdomains": true, "mode": "force-https" },
+ { "name": "trueblueessentials.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tumutanzi.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tuzaijidi.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ubicv.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "un-zero-un.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "unionstationapp.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "utonia.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "victorcanera.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vokeapp.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "waze.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "whitehouse.gov", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wikibooks.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wikimediafoundation.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wikinews.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wikiquote.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wikisource.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wikiversity.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wikivoyage.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wiktionary.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "worcesterfestival.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "x.st", "include_subdomains": true, "mode": "force-https" },
+ { "name": "x64architecture.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xn--datenrettung-mnchen-jbc.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xn--hfk-allgu-schwaben-stb.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xn--mgbbh2a9fub.xn--ngbc5azd", "include_subdomains": true, "mode": "force-https" },
+ { "name": "yippie.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "yu.gg", "include_subdomains": true, "mode": "force-https" },
+ { "name": "zeno-system.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "track.plus", "include_subdomains": true, "mode": "force-https" },
+ { "name": "blog.gov.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "clubmini.jp", "include_subdomains": true, "mode": "force-https" },
+ { "name": "codingforspeed.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cradlepointecm.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dobet.in", "include_subdomains": true, "mode": "force-https" },
+ { "name": "domainexpress.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ediscomp.sk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "edissecurity.sk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ewe2.ninja", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fluxent.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fruitusers.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gpsvideocanada.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gracedays.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "inksupply.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jhburton.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "odin.xxx", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pagure.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pagure.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "silvergoldbull.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "silvergoldbull.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sunnyfruit.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "szaydon.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tosecure.link", "include_subdomains": true, "mode": "force-https" },
+ { "name": "uploadbeta.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wholebites.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wikipedia.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "woresite.jp", "include_subdomains": true, "mode": "force-https" },
+ { "name": "agonswim.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "appharbor.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "armory.consulting", "include_subdomains": true, "mode": "force-https" },
+ { "name": "armory.supplies", "include_subdomains": true, "mode": "force-https" },
+ { "name": "b2and.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bowlroll.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bryanquigley.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cfcnexus.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "clipped4u.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "coffeestrategies.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cvsoftub.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dailyenglishchallenge.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "derreichesack.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "devnsec.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "donateaday.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dragon-chem.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "eelsden.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "elenag.ga", "include_subdomains": true, "mode": "force-https" },
+ { "name": "emailhunter.co", "include_subdomains": true, "mode": "force-https" },
+ { "name": "expressvpn.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "factorygw.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "flamingkeys.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "giveattheoffice.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "givingnexus.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "granth.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "happyfabric.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "happygadget.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "illorenese.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "imirhil.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ipledgeonline.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "junethack.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mamaison.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mca2017.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mnd.sc", "include_subdomains": true, "mode": "force-https" },
+ { "name": "modemagazines.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "n-pix.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "open-to-repair.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "panoti.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "philosophyguides.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pmctire.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "polis.or.at", "include_subdomains": true, "mode": "force-https" },
+ { "name": "quppa.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rc4.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rot47.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rusl.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "satmep.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "secctexasgiving.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "secureideas.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "simod.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "simplycharlottemason.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "skoda-clever-lead.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "skoda-im-dialog.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "skoda-nurdiebesten.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "slix.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "speed-mailer.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "steelephys.com.au", "include_subdomains": true, "mode": "force-https" },
+ { "name": "stick2bike.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "swift-devedge.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "syntaxnightmare.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tbrss.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tokke.dk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "unapp.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "valopv.be", "include_subdomains": true, "mode": "force-https" },
+ { "name": "varvy.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "videomail.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "welovemail.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "whispeer.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wm-talk.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xd.cm", "include_subdomains": true, "mode": "force-https" },
+ { "name": "zaufanatrzeciastrona.pl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "zx6rninja.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "zachborboa.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "alt.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "badcronjob.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bankin.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "boris.one", "include_subdomains": true, "mode": "force-https" },
+ { "name": "brakstad.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bulldog-hosting.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "campus-finance.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cao.la", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cashlink.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ckleemann.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cloud-project.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cloudwalk.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "coore.jp", "include_subdomains": true, "mode": "force-https" },
+ { "name": "crackingking.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "davidgrudl.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "davisroi.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "didacte.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dirkwolf.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dotadata.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dronepit.dk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "duckduckstart.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "e-typ.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "eleicoes2016.com.br", "include_subdomains": true, "mode": "force-https" },
+ { "name": "engelundlicht.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "etaes.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ethicaldata.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "floskelwolke.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "geekcast.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gmta.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "govtrack.us", "include_subdomains": true, "mode": "force-https" },
+ { "name": "guilde-vindicta.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hisbrucker.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hledejlevne.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hookandloom.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hranicka.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hsts.date", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ipv6-adresse.dk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "iqboxy.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ivk.website", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jacekowski.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kermadec.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "latrine.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ldc.com.br", "include_subdomains": true, "mode": "force-https" },
+ { "name": "leominstercu.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lmddgtfy.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lmsptfy.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "madrants.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "marktboten.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "melf.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "meteosky.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mirtes.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mitchellrenouf.ca", "include_subdomains": true, "mode": "force-https" },
+ { "name": "munzee.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "musikkfondene.no", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mydeos.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "myraytech.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nethackwiki.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nette.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "only-roses.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "openkvk.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "phpfashion.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pleier-it.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pleier.it", "include_subdomains": true, "mode": "force-https" },
+ { "name": "recommended.reviews", "include_subdomains": true, "mode": "force-https" },
+ { "name": "reddit.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "remoteutilities.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rj.gg", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rtcx.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "runementors.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rusl.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sellme.biz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "shopapi.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "silentkernel.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "skimming.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "skoleniphp.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "smb445.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sobabox.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "soply.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sweetll.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "taskstream.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thedreamtravelgroup.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thehotfix.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tiffnix.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tomli.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vivendi.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vsean.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wesleycabus.be", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wover.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wpserp.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "z0rro.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "zhihua-lai.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "1017scribes.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "anfsanchezo.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bcvps.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "beautykat.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bevapehappy.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bouncyballs.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bvalle.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cafe-scientifique.org.ec", "include_subdomains": true, "mode": "force-https" },
+ { "name": "caveclan.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "chaletmanager.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "changetip.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ciscodude.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "crysadm.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cuvva.co", "include_subdomains": true, "mode": "force-https" },
+ { "name": "de-spil.be", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dolphin-cloud.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dolphin-hosting.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dolphin-it.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "enquos.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "flipagram.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gravity-net.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gtanda.tk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hannover-banditen.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hdc.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "instacart.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "intarweb.ca", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kirkpatrickdavis.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "maarten.nyc", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mantor.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "motionpicturesolutions.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "motocyklovedily.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "parasitologyclub.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "phongmay24h.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pilgermaske.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pol.in.th", "include_subdomains": true, "mode": "force-https" },
+ { "name": "puyblanc.info", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rantanda.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "redd.it", "include_subdomains": true, "mode": "force-https" },
+ { "name": "respice.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rewardstock.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rr.in.th", "include_subdomains": true, "mode": "force-https" },
+ { "name": "salserototal.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "schallert.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "section.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "secureradio.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "simplelearner.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tlo.link", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tlo.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "typewolf.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vorlif.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xellos.ml", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xn--4dbjwf8c.cf", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xn--4dbjwf8c.ga", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xn--4dbjwf8c.ml", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xn--4dbjwf8c.tk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xn--lgb3a8bcpn.cf", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xn--lgb3a8bcpn.ga", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xn--lgb3a8bcpn.gq", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xn--lgb3a8bcpn.ml", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xn--ls8hi7a.tk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "yyyy.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "zhaojin97.cn", "include_subdomains": true, "mode": "force-https" },
+ { "name": "www.icann.org", "mode": "force-https" },
+ { "name": "368mibn.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "888sport.dk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "aevpn.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "andreigec.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "arnaudfeld.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "beneffy.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "brrr.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "charge.co", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cloudspace-analytics.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "comiteshopping.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "coreless-stretchfilm.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "crudysql.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "csgokings.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dank.ninja", "include_subdomains": true, "mode": "force-https" },
+ { "name": "demuzere.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "demuzere.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "demuzere.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "docucopies.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "elmermx.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "extreemhost.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fabianasantiago.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gamers-life.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "globalinstitutefortraining.org.au", "include_subdomains": true, "mode": "force-https" },
+ { "name": "graingert.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "greenvines.com.tw", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hao2taiwan.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hollowrap.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hostanalyticsconsulting.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hostingactive.it", "include_subdomains": true, "mode": "force-https" },
+ { "name": "humankode.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "immunicity.info", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kahopoon.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "khetzal.info", "include_subdomains": true, "mode": "force-https" },
+ { "name": "koerperimpuls.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lostinsecurity.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mailinabox.email", "include_subdomains": true, "mode": "force-https" },
+ { "name": "malash.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "masjidtawheed.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "newodesign.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nicolaelmer.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ochsundjunior.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "onixcco.com.br", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pctonic.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "photoblogverona.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pluga.co", "include_subdomains": true, "mode": "force-https" },
+ { "name": "prefis.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "prepandgo-euro.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "production.vn", "include_subdomains": true, "mode": "force-https" },
+ { "name": "raconconsulting.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rangde.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "remotestance.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "renuo.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "riskmitigation.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sanhei.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "scaling.solutions", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sifls.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "smkn1lengkong.sch.id", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ssldecoder.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "startupsort.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sx3.no", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tech-seminar.jp", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tncnanet.com.br", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tomo.gr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "utilia.tools", "include_subdomains": true, "mode": "force-https" },
+ { "name": "viewmyrecords.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "www.vino75.com", "include_subdomains": false, "mode": "force-https" },
+ { "name": "vmrdev.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vulnerability.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xiaolan.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xiaoxiao.im", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hana.ondemand.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fastmail.com", "mode": "force-https" },
+ { "name": "www.fastmail.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "3chit.cf", "include_subdomains": true, "mode": "force-https" },
+ { "name": "777coin.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ad-notam.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ad-notam.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ad-notam.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ad-notam.it", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ad-notam.us", "include_subdomains": true, "mode": "force-https" },
+ { "name": "adhs-chaoten.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ageg.ca", "include_subdomains": true, "mode": "force-https" },
+ { "name": "alpca.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "americanbio.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "amoory.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "appmobile.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "attotech.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "aussiecable.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "avarty.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "aylak.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "benny003.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "berthabailey.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bexit.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bitminter.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "blognone.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "borchers-media.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bqtoolbox.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "burningcrash.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "capriccio.to", "include_subdomains": true, "mode": "force-https" },
+ { "name": "certifi.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "clycat.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cogumelosmagicos.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "connect.ua", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cryptobells.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "csfs.org.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cspvalidator.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cubewano.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "deepcovelabs.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "deliciisanatoase.ro", "include_subdomains": true, "mode": "force-https" },
+ { "name": "dienstplan.one", "include_subdomains": true, "mode": "force-https" },
+ { "name": "drbethanybarnes.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "eddmixpanel.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ehipaa.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ehipaadev.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "emanuelduss.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "enjen.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "envygeeks.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "envygeeks.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fayolle.info", "include_subdomains": true, "mode": "force-https" },
+ { "name": "flirchi.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fuglede.dk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gc-mc.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gcs-ventures.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gerencianet.com.br", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gfournier.ca", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gotech.com.eg", "include_subdomains": true, "mode": "force-https" },
+ { "name": "gyboche.science", "include_subdomains": true, "mode": "force-https" },
+ { "name": "hackenturet.dk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "harmoney.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "istheapplestoredown.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jayblock.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "jgid.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "juergenhecht.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kpvpn.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "labrador-retrievers.com.au", "include_subdomains": true, "mode": "force-https" },
+ { "name": "labradorpuppiesforsalebyregisteredlabradorbreeders.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "logement-saisonnier.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lovingearth.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mareklecian.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "maximilian-greger.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mb-is.info", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mbdb.jp", "include_subdomains": true, "mode": "force-https" },
+ { "name": "minecraftforum.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mobile.eti.br", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mosstier.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "motd.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mysecretcase.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "namorico.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "natukusa.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nekomimi.pl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "netprofile.com.au", "include_subdomains": true, "mode": "force-https" },
+ { "name": "numericacu.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "oshayr.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ourevents.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "overkillshop.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pantsu.cat", "include_subdomains": true, "mode": "force-https" },
+ { "name": "paylike.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "peifi.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pennylane.me.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "petko.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pfd-nz.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "pirati.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "plirt.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "qgustavor.tk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rentinsingapore.com.sg", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rideworks.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "riesenweber.id.au", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rivy.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "robi-net.it", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rootservice.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sanasport.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "si-benelux.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "simplednscrypt.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "smartmessages.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "smksi2.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "snapappointments.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "southernutahinfluencers.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "staack.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "stackptr.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "stinkytrashhound.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "stugb.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sunflyer.cn", "include_subdomains": true, "mode": "force-https" },
+ { "name": "swapadoodle.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "syncer.jp", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tannenhof-moelln.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "theintercept.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thinklikeanentrepreneur.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ulabox.cat", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ulabox.es", "include_subdomains": true, "mode": "force-https" },
+ { "name": "umgardi.ca", "include_subdomains": true, "mode": "force-https" },
+ { "name": "upay.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "upstats.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "usgande.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vat-eu.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "veblen.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "viemeister.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "voliere-info.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wait.jp", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wdesk.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wohnsitz-ausland.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "woima.fi", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wolfemg.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wrldevelopment.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xiaody.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xn--t8j4aa4nyhxa7duezbl49aqg5546e264d.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xtremegaming.it", "include_subdomains": true, "mode": "force-https" },
+ { "name": "xunn.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "zdrojak.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "zera.com.au", "include_subdomains": true, "mode": "force-https" },
+ { "name": "0xfc.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "abrilect.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "adduono.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ahmerjamilkhan.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "akombakom.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "alainwolf.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "aulo.in", "include_subdomains": true, "mode": "force-https" },
+ { "name": "beier.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bentrask.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bryn.xyz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cavac.at", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cipherli.st", "include_subdomains": true, "mode": "force-https" },
+ { "name": "claralabs.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "coolaj86.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "coralproject.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "crosscom.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "curroapp.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "daplie.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "darknebula.space", "include_subdomains": true, "mode": "force-https" },
+ { "name": "datapun.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "datsound.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "devlux.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ellsinger.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "excessamerica.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "express-vpn.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "felixrr.pro", "include_subdomains": true, "mode": "force-https" },
+ { "name": "filippo.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "flowlo.me", "include_subdomains": true, "mode": "force-https" },
+ { "name": "flukethoughts.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fraye.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "freedom.press", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fresh-hotel.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "goaltree.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "goldenhillsoftware.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "greenpeace-magazin.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "guineapigmustach.es", "include_subdomains": true, "mode": "force-https" },
+ { "name": "htaccessbook.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "isitup.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kaloix.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kiano.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "krypsys.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lainchan.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lazurit.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lelongbank.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lexway.pk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "libertyrp.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lustrumxi.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "maderwin.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mypagella.eu", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mypagella.it", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mysecretrewards.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nettopower.dk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nicestresser.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "nsboston.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "o7.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "onet.space", "include_subdomains": true, "mode": "force-https" },
+ { "name": "oopsmycase.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "opennippon.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "opennippon.ru", "include_subdomains": true, "mode": "force-https" },
+ { "name": "perishablepress.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "planboardapp.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "plugin-planet.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "qionglu.pw", "include_subdomains": true, "mode": "force-https" },
+ { "name": "redb.cz", "include_subdomains": true, "mode": "force-https" },
+ { "name": "rootforum.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sambeso.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sarasturdivant.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "scourt.org.ua", "include_subdomains": true, "mode": "force-https" },
+ { "name": "secure-games.us", "include_subdomains": true, "mode": "force-https" },
+ { "name": "selecadm.name", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sirenslove.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "smm.im", "include_subdomains": true, "mode": "force-https" },
+ { "name": "stassi.ch", "include_subdomains": true, "mode": "force-https" },
+ { "name": "stephenandburns.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sway-cdn.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "sway.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "thinkindifferent.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tunnelblick.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "typing.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ufotable.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "up1.ca", "include_subdomains": true, "mode": "force-https" },
+ { "name": "vermontcareergateway.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "virtualsanity.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "whatsmychaincert.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wjglerum.nl", "include_subdomains": true, "mode": "force-https" },
+ { "name": "wp-tao.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "yoloprod.fr", "include_subdomains": true, "mode": "force-https" },
+ { "name": "zzsec.org", "include_subdomains": true, "mode": "force-https" }
],
// |ReportUMAOnPinFailure| uses these to report which domain was associated
@@ -3390,6 +4120,12 @@
"CHROME_COM",
"GVT3_COM",
"GVT2_COM",
- "GOOGLE"
+ "GOOGLE",
+ "GGPHT_COM",
+ "BLOGSPOT_COM",
+ "DROPBOXSTATIC_COM",
+ "DROPBOXUSERCONTENT_COM",
+ "WITHYOUTUBE_COM",
+ "WITHGOOGLE_COM"
]
}
diff --git a/chromium/net/http/transport_security_state_unittest.cc b/chromium/net/http/transport_security_state_unittest.cc
index 3b9bf7b96a8..96d6231f5cc 100644
--- a/chromium/net/http/transport_security_state_unittest.cc
+++ b/chromium/net/http/transport_security_state_unittest.cc
@@ -10,10 +10,13 @@
#include "base/base64.h"
#include "base/files/file_path.h"
+#include "base/json/json_reader.h"
#include "base/rand_util.h"
#include "base/sha1.h"
#include "base/strings/string_piece.h"
+#include "base/values.h"
#include "crypto/sha2.h"
+#include "net/base/host_port_pair.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/base/test_data_directory.h"
@@ -37,6 +40,139 @@
namespace net {
+namespace {
+
+const char kHost[] = "example.test";
+const char kSubdomain[] = "foo.example.test";
+const uint16_t kPort = 443;
+const char kReportUri[] = "http://report-example.test/test";
+
+// kGoodPath is blog.torproject.org.
+const char* const kGoodPath[] = {
+ "sha1/Yz4vayd/83rQfDXkDPn2yhzIScw=",
+ "sha1/3lKvjNsfmrn+WmfDhvr2iVh/yRs=",
+ "sha1/gzF+YoVCU9bXeDGQ7JGQVumRueM=",
+ "sha256/4osU79hfY3P2+WJGlT2mxmSL+5FIwLEVxTQcavyBNgQ=",
+ "sha256/k2v657xBsOVe1PQRwOsHsw3bsGT2VzIqz5K+59sNQws=",
+ "sha256/WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=",
+ nullptr,
+};
+
+const char kGoodPin1[] = "4osU79hfY3P2+WJGlT2mxmSL+5FIwLEVxTQcavyBNgQ=";
+const char kGoodPin2[] = "k2v657xBsOVe1PQRwOsHsw3bsGT2VzIqz5K+59sNQws=";
+const char kGoodPin3[] = "WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=";
+
+// kBadPath is plus.google.com via Trustcenter, which is utterly wrong for
+// torproject.org.
+const char* const kBadPath[] = {
+ "sha1/111111111111111111111111111=",
+ "sha1/222222222222222222222222222=",
+ "sha1/333333333333333333333333333=",
+ "sha256/1111111111111111111111111111111111111111111=",
+ "sha256/2222222222222222222222222222222222222222222=",
+ "sha256/3333333333333333333333333333333333333333333=",
+ nullptr,
+};
+
+// A mock ReportSender that just remembers the latest report
+// URI and report to be sent.
+class MockCertificateReportSender
+ : public TransportSecurityState::ReportSender {
+ public:
+ MockCertificateReportSender() {}
+ ~MockCertificateReportSender() override {}
+
+ void Send(const GURL& report_uri, const std::string& report) override {
+ latest_report_uri_ = report_uri;
+ latest_report_ = report;
+ }
+
+ void Clear() {
+ latest_report_uri_ = GURL();
+ latest_report_ = std::string();
+ }
+
+ const GURL& latest_report_uri() { return latest_report_uri_; }
+ const std::string& latest_report() { return latest_report_; }
+
+ private:
+ GURL latest_report_uri_;
+ std::string latest_report_;
+};
+
+void CompareCertificateChainWithList(
+ const scoped_refptr<X509Certificate>& cert_chain,
+ const base::ListValue* cert_list) {
+ ASSERT_TRUE(cert_chain);
+ std::vector<std::string> pem_encoded_chain;
+ cert_chain->GetPEMEncodedChain(&pem_encoded_chain);
+ EXPECT_EQ(pem_encoded_chain.size(), cert_list->GetSize());
+
+ for (size_t i = 0; i < pem_encoded_chain.size(); i++) {
+ std::string list_cert;
+ ASSERT_TRUE(cert_list->GetString(i, &list_cert));
+ EXPECT_EQ(pem_encoded_chain[i], list_cert);
+ }
+}
+
+void CheckHPKPReport(
+ const std::string& report,
+ const HostPortPair& host_port_pair,
+ bool include_subdomains,
+ const std::string& noted_hostname,
+ const scoped_refptr<X509Certificate>& served_certificate_chain,
+ const scoped_refptr<X509Certificate>& validated_certificate_chain,
+ const HashValueVector& known_pins) {
+ scoped_ptr<base::Value> value(base::JSONReader::Read(report));
+ ASSERT_TRUE(value);
+ ASSERT_TRUE(value->IsType(base::Value::TYPE_DICTIONARY));
+
+ base::DictionaryValue* report_dict;
+ ASSERT_TRUE(value->GetAsDictionary(&report_dict));
+
+ std::string report_hostname;
+ EXPECT_TRUE(report_dict->GetString("hostname", &report_hostname));
+ EXPECT_EQ(host_port_pair.host(), report_hostname);
+
+ int report_port;
+ EXPECT_TRUE(report_dict->GetInteger("port", &report_port));
+ EXPECT_EQ(host_port_pair.port(), report_port);
+
+ bool report_include_subdomains;
+ EXPECT_TRUE(report_dict->GetBoolean("include-subdomains",
+ &report_include_subdomains));
+ EXPECT_EQ(include_subdomains, report_include_subdomains);
+
+ std::string report_noted_hostname;
+ EXPECT_TRUE(report_dict->GetString("noted-hostname", &report_noted_hostname));
+ EXPECT_EQ(noted_hostname, report_noted_hostname);
+
+ // TODO(estark): check times in RFC3339 format.
+
+ std::string report_expiration;
+ EXPECT_TRUE(
+ report_dict->GetString("effective-expiration-date", &report_expiration));
+ EXPECT_FALSE(report_expiration.empty());
+
+ std::string report_date;
+ EXPECT_TRUE(report_dict->GetString("date-time", &report_date));
+ EXPECT_FALSE(report_date.empty());
+
+ base::ListValue* report_served_certificate_chain;
+ EXPECT_TRUE(report_dict->GetList("served-certificate-chain",
+ &report_served_certificate_chain));
+ ASSERT_NO_FATAL_FAILURE(CompareCertificateChainWithList(
+ served_certificate_chain, report_served_certificate_chain));
+
+ base::ListValue* report_validated_certificate_chain;
+ EXPECT_TRUE(report_dict->GetList("validated-certificate-chain",
+ &report_validated_certificate_chain));
+ ASSERT_NO_FATAL_FAILURE(CompareCertificateChainWithList(
+ validated_certificate_chain, report_validated_certificate_chain));
+}
+
+} // namespace
+
class TransportSecurityStateTest : public testing::Test {
public:
void SetUp() override {
@@ -57,7 +193,7 @@ class TransportSecurityStateTest : public testing::Test {
static HashValueVector GetSampleSPKIHashes() {
HashValueVector spki_hashes;
- HashValue hash(HASH_VALUE_SHA1);
+ HashValue hash(HASH_VALUE_SHA256);
memset(hash.data(), 0, hash.size());
spki_hashes.push_back(hash);
return spki_hashes;
@@ -214,6 +350,7 @@ TEST_F(TransportSecurityStateTest, SubdomainMatches) {
// with it, regardless of the includeSubDomains bit. This is a regression test
// for https://crbug.com/469957.
TEST_F(TransportSecurityStateTest, SubdomainCarveout) {
+ const GURL report_uri(kReportUri);
TransportSecurityState state;
const base::Time current_time(base::Time::Now());
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
@@ -222,8 +359,10 @@ TEST_F(TransportSecurityStateTest, SubdomainCarveout) {
state.AddHSTS("example1.test", expiry, true);
state.AddHSTS("foo.example1.test", expiry, false);
- state.AddHPKP("example2.test", expiry, true, GetSampleSPKIHashes());
- state.AddHPKP("foo.example2.test", expiry, false, GetSampleSPKIHashes());
+ state.AddHPKP("example2.test", expiry, true, GetSampleSPKIHashes(),
+ report_uri);
+ state.AddHPKP("foo.example2.test", expiry, false, GetSampleSPKIHashes(),
+ report_uri);
EXPECT_TRUE(state.ShouldUpgradeToSSL("example1.test"));
EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.example1.test"));
@@ -243,7 +382,8 @@ TEST_F(TransportSecurityStateTest, SubdomainCarveout) {
// Expire the foo.example*.test rules.
state.AddHSTS("foo.example1.test", older, false);
- state.AddHPKP("foo.example2.test", older, false, GetSampleSPKIHashes());
+ state.AddHPKP("foo.example2.test", older, false, GetSampleSPKIHashes(),
+ report_uri);
// Now the base example*.test rules apply to bar.foo.example*.test.
EXPECT_TRUE(state.ShouldUpgradeToSSL("bar.foo.example1.test"));
@@ -253,12 +393,14 @@ TEST_F(TransportSecurityStateTest, SubdomainCarveout) {
}
TEST_F(TransportSecurityStateTest, FatalSSLErrors) {
+ const GURL report_uri(kReportUri);
TransportSecurityState state;
const base::Time current_time(base::Time::Now());
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
state.AddHSTS("example1.test", expiry, false);
- state.AddHPKP("example2.test", expiry, false, GetSampleSPKIHashes());
+ state.AddHPKP("example2.test", expiry, false, GetSampleSPKIHashes(),
+ report_uri);
// The presense of either HSTS or HPKP is enough to make SSL errors fatal.
EXPECT_TRUE(state.ShouldSSLErrorsBeFatal("example1.test"));
@@ -268,6 +410,7 @@ TEST_F(TransportSecurityStateTest, FatalSSLErrors) {
// Tests that HPKP and HSTS state both expire. Also tests that expired entries
// are pruned.
TEST_F(TransportSecurityStateTest, Expiration) {
+ const GURL report_uri(kReportUri);
TransportSecurityState state;
const base::Time current_time(base::Time::Now());
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
@@ -281,14 +424,16 @@ TEST_F(TransportSecurityStateTest, Expiration) {
// Querying |state| for a domain should flush out expired entries.
EXPECT_FALSE(TransportSecurityState::STSStateIterator(state).HasNext());
- state.AddHPKP("example1.test", older, false, GetSampleSPKIHashes());
+ state.AddHPKP("example1.test", older, false, GetSampleSPKIHashes(),
+ report_uri);
EXPECT_TRUE(TransportSecurityState::PKPStateIterator(state).HasNext());
EXPECT_FALSE(state.HasPublicKeyPins("example1.test"));
// Querying |state| for a domain should flush out expired entries.
EXPECT_FALSE(TransportSecurityState::PKPStateIterator(state).HasNext());
state.AddHSTS("example1.test", older, false);
- state.AddHPKP("example1.test", older, false, GetSampleSPKIHashes());
+ state.AddHPKP("example1.test", older, false, GetSampleSPKIHashes(),
+ report_uri);
EXPECT_TRUE(TransportSecurityState::STSStateIterator(state).HasNext());
EXPECT_TRUE(TransportSecurityState::PKPStateIterator(state).HasNext());
EXPECT_FALSE(state.ShouldSSLErrorsBeFatal("example1.test"));
@@ -298,13 +443,15 @@ TEST_F(TransportSecurityStateTest, Expiration) {
// Test that HSTS can outlive HPKP.
state.AddHSTS("example1.test", expiry, false);
- state.AddHPKP("example1.test", older, false, GetSampleSPKIHashes());
+ state.AddHPKP("example1.test", older, false, GetSampleSPKIHashes(),
+ report_uri);
EXPECT_TRUE(state.ShouldUpgradeToSSL("example1.test"));
EXPECT_FALSE(state.HasPublicKeyPins("example1.test"));
// Test that HPKP can outlive HSTS.
state.AddHSTS("example2.test", older, false);
- state.AddHPKP("example2.test", expiry, false, GetSampleSPKIHashes());
+ state.AddHPKP("example2.test", expiry, false, GetSampleSPKIHashes(),
+ report_uri);
EXPECT_FALSE(state.ShouldUpgradeToSSL("example2.test"));
EXPECT_TRUE(state.HasPublicKeyPins("example2.test"));
}
@@ -324,15 +471,18 @@ TEST_F(TransportSecurityStateTest, InvalidDomains) {
// Tests that HPKP and HSTS state are queried independently for subdomain
// matches.
TEST_F(TransportSecurityStateTest, IndependentSubdomain) {
+ const GURL report_uri(kReportUri);
TransportSecurityState state;
const base::Time current_time(base::Time::Now());
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
state.AddHSTS("example1.test", expiry, true);
- state.AddHPKP("example1.test", expiry, false, GetSampleSPKIHashes());
+ state.AddHPKP("example1.test", expiry, false, GetSampleSPKIHashes(),
+ report_uri);
state.AddHSTS("example2.test", expiry, false);
- state.AddHPKP("example2.test", expiry, true, GetSampleSPKIHashes());
+ state.AddHPKP("example2.test", expiry, true, GetSampleSPKIHashes(),
+ report_uri);
EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.example1.test"));
EXPECT_FALSE(state.HasPublicKeyPins("foo.example1.test"));
@@ -342,13 +492,15 @@ TEST_F(TransportSecurityStateTest, IndependentSubdomain) {
// Tests that HPKP and HSTS state are inserted and overridden independently.
TEST_F(TransportSecurityStateTest, IndependentInsertion) {
+ const GURL report_uri(kReportUri);
TransportSecurityState state;
const base::Time current_time(base::Time::Now());
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
// Place an includeSubdomains HSTS entry below a normal HPKP entry.
state.AddHSTS("example1.test", expiry, true);
- state.AddHPKP("foo.example1.test", expiry, false, GetSampleSPKIHashes());
+ state.AddHPKP("foo.example1.test", expiry, false, GetSampleSPKIHashes(),
+ report_uri);
EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.example1.test"));
EXPECT_TRUE(state.HasPublicKeyPins("foo.example1.test"));
@@ -363,13 +515,15 @@ TEST_F(TransportSecurityStateTest, IndependentInsertion) {
// Place an includeSubdomains HPKP entry below a normal HSTS entry.
state.AddHSTS("foo.example2.test", expiry, false);
- state.AddHPKP("example2.test", expiry, true, GetSampleSPKIHashes());
+ state.AddHPKP("example2.test", expiry, true, GetSampleSPKIHashes(),
+ report_uri);
EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.example2.test"));
EXPECT_TRUE(state.HasPublicKeyPins("foo.example2.test"));
// Drop the includeSubdomains from the HSTS entry.
- state.AddHPKP("example2.test", expiry, false, GetSampleSPKIHashes());
+ state.AddHPKP("example2.test", expiry, false, GetSampleSPKIHashes(),
+ report_uri);
EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.example2.test"));
EXPECT_FALSE(state.HasPublicKeyPins("foo.example2.test"));
@@ -378,13 +532,15 @@ TEST_F(TransportSecurityStateTest, IndependentInsertion) {
// Tests that GetDynamic[PKP|STS]State returns the correct data and that the
// states are not mixed together.
TEST_F(TransportSecurityStateTest, DynamicDomainState) {
+ const GURL report_uri(kReportUri);
TransportSecurityState state;
const base::Time current_time(base::Time::Now());
const base::Time expiry1 = current_time + base::TimeDelta::FromSeconds(1000);
const base::Time expiry2 = current_time + base::TimeDelta::FromSeconds(2000);
state.AddHSTS("example.com", expiry1, true);
- state.AddHPKP("foo.example.com", expiry2, false, GetSampleSPKIHashes());
+ state.AddHPKP("foo.example.com", expiry2, false, GetSampleSPKIHashes(),
+ report_uri);
TransportSecurityState::STSState sts_state;
TransportSecurityState::PKPState pkp_state;
@@ -403,30 +559,34 @@ TEST_F(TransportSecurityStateTest, DynamicDomainState) {
// Tests that new pins always override previous pins. This should be true for
// both pins at the same domain or includeSubdomains pins at a parent domain.
TEST_F(TransportSecurityStateTest, NewPinsOverride) {
+ const GURL report_uri(kReportUri);
TransportSecurityState state;
TransportSecurityState::PKPState pkp_state;
const base::Time current_time(base::Time::Now());
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
- HashValue hash1(HASH_VALUE_SHA1);
+ HashValue hash1(HASH_VALUE_SHA256);
memset(hash1.data(), 0x01, hash1.size());
- HashValue hash2(HASH_VALUE_SHA1);
+ HashValue hash2(HASH_VALUE_SHA256);
memset(hash2.data(), 0x02, hash1.size());
- HashValue hash3(HASH_VALUE_SHA1);
+ HashValue hash3(HASH_VALUE_SHA256);
memset(hash3.data(), 0x03, hash1.size());
- state.AddHPKP("example.com", expiry, true, HashValueVector(1, hash1));
+ state.AddHPKP("example.com", expiry, true, HashValueVector(1, hash1),
+ report_uri);
ASSERT_TRUE(state.GetDynamicPKPState("foo.example.com", &pkp_state));
ASSERT_EQ(1u, pkp_state.spki_hashes.size());
EXPECT_TRUE(pkp_state.spki_hashes[0].Equals(hash1));
- state.AddHPKP("foo.example.com", expiry, false, HashValueVector(1, hash2));
+ state.AddHPKP("foo.example.com", expiry, false, HashValueVector(1, hash2),
+ report_uri);
ASSERT_TRUE(state.GetDynamicPKPState("foo.example.com", &pkp_state));
ASSERT_EQ(1u, pkp_state.spki_hashes.size());
EXPECT_TRUE(pkp_state.spki_hashes[0].Equals(hash2));
- state.AddHPKP("foo.example.com", expiry, false, HashValueVector(1, hash3));
+ state.AddHPKP("foo.example.com", expiry, false, HashValueVector(1, hash3),
+ report_uri);
ASSERT_TRUE(state.GetDynamicPKPState("foo.example.com", &pkp_state));
ASSERT_EQ(1u, pkp_state.spki_hashes.size());
@@ -444,7 +604,7 @@ TEST_F(TransportSecurityStateTest, DeleteAllDynamicDataSince) {
bool include_subdomains = false;
state.AddHSTS("example.com", expiry, include_subdomains);
state.AddHPKP("example.com", expiry, include_subdomains,
- GetSampleSPKIHashes());
+ GetSampleSPKIHashes(), GURL());
state.DeleteAllDynamicDataSince(expiry);
EXPECT_TRUE(state.ShouldUpgradeToSSL("example.com"));
@@ -466,7 +626,7 @@ TEST_F(TransportSecurityStateTest, DeleteDynamicDataForHost) {
state.AddHSTS("example1.test", expiry, include_subdomains);
state.AddHPKP("example1.test", expiry, include_subdomains,
- GetSampleSPKIHashes());
+ GetSampleSPKIHashes(), GURL());
EXPECT_TRUE(state.ShouldUpgradeToSSL("example1.test"));
EXPECT_FALSE(state.ShouldUpgradeToSSL("example2.test"));
@@ -940,23 +1100,6 @@ static bool AddHash(const std::string& type_and_base64,
}
TEST_F(TransportSecurityStateTest, PinValidationWithoutRejectedCerts) {
- // kGoodPath is blog.torproject.org.
- static const char* const kGoodPath[] = {
- "sha1/m9lHYJYke9k0GtVZ+bXSQYE8nDI=",
- "sha1/o5OZxATDsgmwgcIfIWIneMJ0jkw=",
- "sha1/wHqYaI2J+6sFZAwRfap9ZbjKzE4=",
- NULL,
- };
-
- // kBadPath is plus.google.com via Trustcenter, which is utterly wrong for
- // torproject.org.
- static const char* const kBadPath[] = {
- "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=",
- "sha1/gzuEEAB/bkqdQS3EIjk2by7lW+k=",
- "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=",
- NULL,
- };
-
HashValueVector good_hashes, bad_hashes;
for (size_t i = 0; kGoodPath[i]; i++) {
@@ -1082,4 +1225,317 @@ TEST_F(TransportSecurityStateTest, GooglePinnedProperties) {
"www.googlegroups.com"));
}
+TEST_F(TransportSecurityStateTest, HPKPReporting) {
+ HostPortPair host_port_pair(kHost, kPort);
+ HostPortPair subdomain_host_port_pair(kSubdomain, kPort);
+ GURL report_uri(kReportUri);
+ // Two dummy certs to use as the server-sent and validated chains. The
+ // contents don't matter.
+ scoped_refptr<X509Certificate> cert1 =
+ ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
+ scoped_refptr<X509Certificate> cert2 =
+ ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
+ ASSERT_TRUE(cert1);
+ ASSERT_TRUE(cert2);
+
+ HashValueVector good_hashes, bad_hashes;
+
+ for (size_t i = 0; kGoodPath[i]; i++)
+ EXPECT_TRUE(AddHash(kGoodPath[i], &good_hashes));
+ for (size_t i = 0; kBadPath[i]; i++)
+ EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes));
+
+ TransportSecurityState state;
+ MockCertificateReportSender mock_report_sender;
+ state.SetReportSender(&mock_report_sender);
+
+ const base::Time current_time = base::Time::Now();
+ const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
+ state.AddHPKP(kHost, expiry, true, good_hashes, report_uri);
+
+ EXPECT_EQ(GURL(), mock_report_sender.latest_report_uri());
+ EXPECT_EQ(std::string(), mock_report_sender.latest_report());
+
+ std::string failure_log;
+ EXPECT_FALSE(state.CheckPublicKeyPins(
+ host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
+ TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log));
+
+ // No report should have been sent because of the DISABLE_PIN_REPORTS
+ // argument.
+ EXPECT_EQ(GURL(), mock_report_sender.latest_report_uri());
+ EXPECT_EQ(std::string(), mock_report_sender.latest_report());
+
+ EXPECT_TRUE(state.CheckPublicKeyPins(
+ host_port_pair, true, good_hashes, cert1.get(), cert2.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
+
+ // No report should have been sent because there was no violation.
+ EXPECT_EQ(GURL(), mock_report_sender.latest_report_uri());
+ EXPECT_EQ(std::string(), mock_report_sender.latest_report());
+
+ EXPECT_FALSE(state.CheckPublicKeyPins(
+ host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
+
+ // Now a report should have been sent. Check that it contains the
+ // right information.
+ EXPECT_EQ(report_uri, mock_report_sender.latest_report_uri());
+ std::string report = mock_report_sender.latest_report();
+ ASSERT_FALSE(report.empty());
+ ASSERT_NO_FATAL_FAILURE(CheckHPKPReport(report, host_port_pair, true, kHost,
+ cert1.get(), cert2.get(),
+ good_hashes));
+ mock_report_sender.Clear();
+ EXPECT_FALSE(state.CheckPublicKeyPins(
+ subdomain_host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
+
+ // Now a report should have been sent for the subdomain. Check that it
+ // contains the right information.
+ EXPECT_EQ(report_uri, mock_report_sender.latest_report_uri());
+ report = mock_report_sender.latest_report();
+ ASSERT_FALSE(report.empty());
+ ASSERT_NO_FATAL_FAILURE(CheckHPKPReport(report, subdomain_host_port_pair,
+ true, kHost, cert1.get(), cert2.get(),
+ good_hashes));
+}
+
+TEST_F(TransportSecurityStateTest, HPKPReportOnly) {
+ HostPortPair host_port_pair(kHost, kPort);
+ GURL report_uri(kReportUri);
+ // Two dummy certs to use as the server-sent and validated chains. The
+ // contents don't matter.
+ scoped_refptr<X509Certificate> cert1 =
+ ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
+ scoped_refptr<X509Certificate> cert2 =
+ ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
+ ASSERT_TRUE(cert1);
+ ASSERT_TRUE(cert2);
+
+ TransportSecurityState state;
+ MockCertificateReportSender mock_report_sender;
+ state.SetReportSender(&mock_report_sender);
+
+ // Check that a report is not sent for a Report-Only header with no
+ // violation.
+ std::string header =
+ "pin-sha256=\"" + std::string(kGoodPin1) + "\";pin-sha256=\"" +
+ std::string(kGoodPin2) + "\";pin-sha256=\"" + std::string(kGoodPin3) +
+ "\";report-uri=\"" + report_uri.spec() + "\";includeSubdomains";
+ SSLInfo ssl_info;
+ ssl_info.is_issued_by_known_root = true;
+ ssl_info.unverified_cert = cert1;
+ ssl_info.cert = cert2;
+ for (size_t i = 0; kGoodPath[i]; i++)
+ EXPECT_TRUE(AddHash(kGoodPath[i], &ssl_info.public_key_hashes));
+
+ EXPECT_TRUE(
+ state.ProcessHPKPReportOnlyHeader(header, host_port_pair, ssl_info));
+ EXPECT_EQ(GURL(), mock_report_sender.latest_report_uri());
+ EXPECT_EQ(std::string(), mock_report_sender.latest_report());
+
+ // Check that a report is sent for a Report-Only header with a
+ // violation.
+ ssl_info.public_key_hashes.clear();
+ for (size_t i = 0; kBadPath[i]; i++)
+ EXPECT_TRUE(AddHash(kBadPath[i], &ssl_info.public_key_hashes));
+
+ EXPECT_TRUE(
+ state.ProcessHPKPReportOnlyHeader(header, host_port_pair, ssl_info));
+ EXPECT_EQ(report_uri, mock_report_sender.latest_report_uri());
+ std::string report = mock_report_sender.latest_report();
+ ASSERT_FALSE(report.empty());
+ ASSERT_NO_FATAL_FAILURE(CheckHPKPReport(report, host_port_pair, true, kHost,
+ cert1.get(), cert2.get(),
+ ssl_info.public_key_hashes));
+
+ // HTTPS report URIs on the same host as the pin violation should not
+ // be allowed, to avoid going into a report-sending loop.
+ mock_report_sender.Clear();
+ header = "pin-sha256=\"" + std::string(kGoodPin1) + "\";pin-sha256=\"" +
+ std::string(kGoodPin2) + "\";pin-sha256=\"" +
+ std::string(kGoodPin3) + "\";report-uri=\"https://" +
+ host_port_pair.host() + "/report\";includeSubdomains";
+ EXPECT_TRUE(
+ state.ProcessHPKPReportOnlyHeader(header, host_port_pair, ssl_info));
+ EXPECT_TRUE(mock_report_sender.latest_report_uri().is_empty());
+}
+
+// Tests that Report-Only reports are not sent on certs that chain to
+// local roots.
+TEST_F(TransportSecurityStateTest, HPKPReportOnlyOnLocalRoot) {
+ HostPortPair host_port_pair(kHost, kPort);
+ GURL report_uri(kReportUri);
+ // Two dummy certs to use as the server-sent and validated chains. The
+ // contents don't matter.
+ scoped_refptr<X509Certificate> cert1 =
+ ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
+ scoped_refptr<X509Certificate> cert2 =
+ ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
+ ASSERT_TRUE(cert1);
+ ASSERT_TRUE(cert2);
+
+ std::string header =
+ "pin-sha256=\"" + std::string(kGoodPin1) + "\";pin-sha256=\"" +
+ std::string(kGoodPin2) + "\";pin-sha256=\"" + std::string(kGoodPin3) +
+ "\";report-uri=\"" + report_uri.spec() + "\";includeSubdomains";
+
+ TransportSecurityState state;
+ MockCertificateReportSender mock_report_sender;
+ state.SetReportSender(&mock_report_sender);
+
+ SSLInfo ssl_info;
+ ssl_info.is_issued_by_known_root = true;
+ ssl_info.unverified_cert = cert1;
+ ssl_info.cert = cert2;
+ for (size_t i = 0; kGoodPath[i]; i++)
+ EXPECT_TRUE(AddHash(kGoodPath[i], &ssl_info.public_key_hashes));
+ ssl_info.is_issued_by_known_root = false;
+
+ EXPECT_TRUE(
+ state.ProcessHPKPReportOnlyHeader(header, host_port_pair, ssl_info));
+ EXPECT_EQ(GURL(), mock_report_sender.latest_report_uri());
+ EXPECT_EQ(std::string(), mock_report_sender.latest_report());
+}
+
+// Tests that ProcessHPKPReportOnlyHeader() returns false if a report-uri
+// wasn't specified or if the header fails to parse.
+TEST_F(TransportSecurityStateTest, HPKPReportOnlyParseErrors) {
+ HostPortPair host_port_pair(kHost, kPort);
+ GURL report_uri(kReportUri);
+ // Two dummy certs to use as the server-sent and validated chains. The
+ // contents don't matter.
+ scoped_refptr<X509Certificate> cert1 =
+ ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
+ scoped_refptr<X509Certificate> cert2 =
+ ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
+ ASSERT_TRUE(cert1);
+ ASSERT_TRUE(cert2);
+
+ std::string header = "pin-sha256=\"" + std::string(kGoodPin1) +
+ "\";pin-sha256=\"" + std::string(kGoodPin2) +
+ "\";pin-sha256=\"" + std::string(kGoodPin3) + "\"";
+
+ TransportSecurityState state;
+ MockCertificateReportSender mock_report_sender;
+ state.SetReportSender(&mock_report_sender);
+
+ SSLInfo ssl_info;
+ ssl_info.is_issued_by_known_root = true;
+ ssl_info.unverified_cert = cert1;
+ ssl_info.cert = cert2;
+ for (size_t i = 0; kGoodPath[i]; i++)
+ EXPECT_TRUE(AddHash(kGoodPath[i], &ssl_info.public_key_hashes));
+
+ EXPECT_FALSE(
+ state.ProcessHPKPReportOnlyHeader(header, host_port_pair, ssl_info));
+ header += ";report-uri=\"";
+ EXPECT_FALSE(
+ state.ProcessHPKPReportOnlyHeader(header, host_port_pair, ssl_info));
+}
+
+// Tests that pinning violations on preloaded pins trigger reports when
+// the preloaded pin contains a report URI.
+TEST_F(TransportSecurityStateTest, PreloadedPKPReportUri) {
+ const char kPreloadedPinDomain[] = "www.google.com";
+ const uint16_t kPort = 443;
+ HostPortPair host_port_pair(kPreloadedPinDomain, kPort);
+
+ TransportSecurityState state;
+ MockCertificateReportSender mock_report_sender;
+ state.SetReportSender(&mock_report_sender);
+
+ ASSERT_TRUE(
+ TransportSecurityState::IsGooglePinnedProperty(kPreloadedPinDomain));
+ EnableStaticPins(&state);
+
+ TransportSecurityState::PKPState pkp_state;
+ TransportSecurityState::STSState unused_sts_state;
+ ASSERT_TRUE(state.GetStaticDomainState(kPreloadedPinDomain, &unused_sts_state,
+ &pkp_state));
+
+ GURL report_uri = pkp_state.report_uri;
+ ASSERT_TRUE(report_uri.is_valid());
+ ASSERT_FALSE(report_uri.is_empty());
+
+ // Two dummy certs to use as the server-sent and validated chains. The
+ // contents don't matter, as long as they are not the real google.com
+ // certs in the pins.
+ scoped_refptr<X509Certificate> cert1 =
+ ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
+ scoped_refptr<X509Certificate> cert2 =
+ ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
+ ASSERT_TRUE(cert1);
+ ASSERT_TRUE(cert2);
+
+ HashValueVector bad_hashes;
+ for (size_t i = 0; kBadPath[i]; i++)
+ EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes));
+
+ // Trigger a violation and check that it sends a report.
+ std::string failure_log;
+ EXPECT_FALSE(state.CheckPublicKeyPins(
+ host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
+
+ EXPECT_EQ(report_uri, mock_report_sender.latest_report_uri());
+
+ std::string report = mock_report_sender.latest_report();
+ ASSERT_FALSE(report.empty());
+ ASSERT_NO_FATAL_FAILURE(CheckHPKPReport(
+ report, host_port_pair, pkp_state.include_subdomains, pkp_state.domain,
+ cert1.get(), cert2.get(), pkp_state.spki_hashes));
+}
+
+// Tests that report URIs are thrown out if they point to the same host,
+// over HTTPS, for which a pin was violated.
+TEST_F(TransportSecurityStateTest, HPKPReportUriToSameHost) {
+ HostPortPair host_port_pair(kHost, kPort);
+ GURL https_report_uri("https://example.test/report");
+ GURL http_report_uri("http://example.test/report");
+ TransportSecurityState state;
+ MockCertificateReportSender mock_report_sender;
+ state.SetReportSender(&mock_report_sender);
+
+ const base::Time current_time = base::Time::Now();
+ const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
+ HashValueVector good_hashes;
+ for (size_t i = 0; kGoodPath[i]; i++)
+ EXPECT_TRUE(AddHash(kGoodPath[i], &good_hashes));
+
+ // Two dummy certs to use as the server-sent and validated chains. The
+ // contents don't matter, as long as they are not the real google.com
+ // certs in the pins.
+ scoped_refptr<X509Certificate> cert1 =
+ ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
+ scoped_refptr<X509Certificate> cert2 =
+ ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
+ ASSERT_TRUE(cert1);
+ ASSERT_TRUE(cert2);
+
+ HashValueVector bad_hashes;
+ for (size_t i = 0; kBadPath[i]; i++)
+ EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes));
+
+ state.AddHPKP(kHost, expiry, true, good_hashes, https_report_uri);
+
+ // Trigger a violation and check that it does not send a report
+ // because the report-uri is HTTPS and same-host as the pins.
+ std::string failure_log;
+ EXPECT_FALSE(state.CheckPublicKeyPins(
+ host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
+
+ EXPECT_TRUE(mock_report_sender.latest_report_uri().is_empty());
+
+ // An HTTP report uri to the same host should be okay.
+ state.AddHPKP("example.test", expiry, true, good_hashes, http_report_uri);
+ EXPECT_FALSE(state.CheckPublicKeyPins(
+ host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
+
+ EXPECT_EQ(http_report_uri, mock_report_sender.latest_report_uri());
+}
+
} // namespace net