summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornikita <nikita@NetBSD.org>2021-01-13 00:53:52 +0100
committernikita <nikita@NetBSD.org>2021-01-13 00:53:52 +0100
commit5b9f8acdda96cbaf7ec070db3ae9bdbe2a42f8eb (patch)
treed69e840805484efba1885154b855bf93409248cb
parent7bd28f37397837d72302550e43d95060413e9eb8 (diff)
parente052859759b34d0e05ce0f17244873e5cd7b457b (diff)
downloadgnurl-5b9f8acdda96cbaf7ec070db3ae9bdbe2a42f8eb.tar.gz
gnurl-5b9f8acdda96cbaf7ec070db3ae9bdbe2a42f8eb.tar.bz2
gnurl-5b9f8acdda96cbaf7ec070db3ae9bdbe2a42f8eb.zip
Merge tag 'curl-7_74_0'
7.74.0
-rw-r--r--.azure-pipelines.yml31
-rw-r--r--.cirrus.yml16
-rw-r--r--.dir-locals.el2
-rw-r--r--.github/ISSUE_TEMPLATE/config.yml11
-rw-r--r--.lgtm.yml2
-rw-r--r--.mailmap10
-rw-r--r--.travis.yml317
-rw-r--r--CHANGES2
-rw-r--r--CMake/CMakeConfigurableFile.in2
-rw-r--r--CMake/CurlSymbolHiding.cmake4
-rw-r--r--CMake/CurlTests.c4
-rw-r--r--CMake/FindBearSSL.cmake2
-rw-r--r--CMake/FindGSS.cmake2
-rw-r--r--CMake/FindNGHTTP3.cmake2
-rw-r--r--CMake/FindNGTCP2.cmake2
-rw-r--r--CMake/FindNSS.cmake2
-rw-r--r--CMake/FindQUICHE.cmake2
-rw-r--r--CMake/FindWolfSSL.cmake2
-rw-r--r--CMake/FindZstd.cmake2
-rw-r--r--CMake/Macros.cmake13
-rw-r--r--CMake/OtherTests.cmake2
-rw-r--r--CMake/Platforms/WindowsCache.cmake2
-rw-r--r--CMake/Utilities.cmake2
-rw-r--r--CMake/cmake_uninstall.cmake.in2
-rw-r--r--CMake/gnurl-config.cmake.in2
-rw-r--r--CMakeLists.txt104
-rwxr-xr-xMacOSX-Framework2
-rw-r--r--Makefile.am3
-rw-r--r--Makefile.dist16
-rw-r--r--README10
-rw-r--r--README.md29
-rw-r--r--RELEASE-NOTES452
-rw-r--r--acinclude.m438
-rw-r--r--appveyor.yml34
-rwxr-xr-xbuildconf432
-rw-r--r--buildconf.bat2
-rwxr-xr-xconfigure.ac181
-rw-r--r--docs/ALTSVC.md4
-rw-r--r--docs/BUGS302
-rw-r--r--docs/BUGS.md266
-rw-r--r--docs/CHECKSRC.md6
-rw-r--r--docs/CIPHERS.md8
-rw-r--r--docs/CMakeLists.txt2
-rw-r--r--docs/CONTRIBUTE.md45
-rw-r--r--docs/CURL-DISABLE.md18
-rw-r--r--docs/DYNBUF.md6
-rw-r--r--docs/ECH.md (renamed from docs/ESNI.md)76
-rw-r--r--docs/EXPERIMENTAL.md4
-rw-r--r--docs/FAQ267
-rw-r--r--docs/FEATURES.md (renamed from docs/FEATURES)182
-rw-r--r--docs/HELP-US.md8
-rw-r--r--docs/HISTORY.md40
-rw-r--r--docs/HSTS.md44
-rw-r--r--docs/HTTP-COOKIES.md2
-rw-r--r--docs/HTTP3.md16
-rw-r--r--docs/INTERNALS.md49
-rw-r--r--docs/KNOWN_BUGS200
-rw-r--r--docs/LICENSE-MIXING.md128
-rw-r--r--docs/MAIL-ETIQUETTE2
-rw-r--r--docs/MANUAL.md28
-rw-r--r--docs/MQTT.md32
-rw-r--r--docs/Makefile.am14
-rw-r--r--docs/NEW-PROTOCOL.md110
-rw-r--r--docs/README.md6
-rw-r--r--docs/RESOURCES85
-rw-r--r--docs/ROADMAP.md32
-rw-r--r--docs/SECURITY-PROCESS.md12
-rw-r--r--docs/SSL-PROBLEMS.md2
-rw-r--r--docs/SSLCERTS.md6
-rw-r--r--docs/THANKS53
-rw-r--r--docs/THANKS-filter3
-rw-r--r--docs/TODO58
-rw-r--r--docs/TheArtOfHttpScripting758
-rw-r--r--docs/TheArtOfHttpScripting.md692
-rw-r--r--docs/VERSIONS.md13
-rw-r--r--docs/cmdline-opts/CMakeLists.txt2
-rw-r--r--docs/cmdline-opts/Makefile.am2
-rw-r--r--docs/cmdline-opts/Makefile.inc5
-rw-r--r--docs/cmdline-opts/abstract-unix-socket.d1
-rw-r--r--docs/cmdline-opts/alt-svc.d1
-rw-r--r--docs/cmdline-opts/anyauth.d1
-rw-r--r--docs/cmdline-opts/append.d1
-rw-r--r--docs/cmdline-opts/basic.d1
-rw-r--r--docs/cmdline-opts/cacert.d1
-rw-r--r--docs/cmdline-opts/capath.d1
-rw-r--r--docs/cmdline-opts/cert-status.d1
-rw-r--r--docs/cmdline-opts/cert-type.d1
-rw-r--r--docs/cmdline-opts/cert.d1
-rw-r--r--docs/cmdline-opts/ciphers.d3
-rw-r--r--docs/cmdline-opts/compressed-ssh.d1
-rw-r--r--docs/cmdline-opts/compressed.d1
-rw-r--r--docs/cmdline-opts/config.d21
-rw-r--r--docs/cmdline-opts/connect-timeout.d1
-rw-r--r--docs/cmdline-opts/connect-to.d1
-rw-r--r--docs/cmdline-opts/continue-at.d1
-rw-r--r--docs/cmdline-opts/cookie-jar.d1
-rw-r--r--docs/cmdline-opts/cookie.d1
-rw-r--r--docs/cmdline-opts/create-dirs.d1
-rw-r--r--docs/cmdline-opts/crlf.d1
-rw-r--r--docs/cmdline-opts/crlfile.d1
-rw-r--r--docs/cmdline-opts/curves.d18
-rw-r--r--docs/cmdline-opts/data-ascii.d1
-rw-r--r--docs/cmdline-opts/data-binary.d1
-rw-r--r--docs/cmdline-opts/data-raw.d1
-rw-r--r--docs/cmdline-opts/data-urlencode.d1
-rw-r--r--docs/cmdline-opts/data.d1
-rw-r--r--docs/cmdline-opts/delegation.d1
-rw-r--r--docs/cmdline-opts/digest.d1
-rw-r--r--docs/cmdline-opts/disable-eprt.d1
-rw-r--r--docs/cmdline-opts/disable-epsv.d1
-rw-r--r--docs/cmdline-opts/disable.d1
-rw-r--r--docs/cmdline-opts/disallow-username-in-url.d1
-rw-r--r--docs/cmdline-opts/dns-interface.d1
-rw-r--r--docs/cmdline-opts/dns-ipv4-addr.d1
-rw-r--r--docs/cmdline-opts/dns-ipv6-addr.d1
-rw-r--r--docs/cmdline-opts/dns-servers.d1
-rw-r--r--docs/cmdline-opts/doh-url.d1
-rw-r--r--docs/cmdline-opts/dump-header.d1
-rw-r--r--docs/cmdline-opts/egd-file.d1
-rw-r--r--docs/cmdline-opts/engine.d1
-rw-r--r--docs/cmdline-opts/etag-compare.d3
-rw-r--r--docs/cmdline-opts/etag-save.d5
-rw-r--r--docs/cmdline-opts/expect100-timeout.d1
-rw-r--r--docs/cmdline-opts/fail-early.d1
-rw-r--r--docs/cmdline-opts/fail.d1
-rw-r--r--docs/cmdline-opts/false-start.d1
-rw-r--r--docs/cmdline-opts/form-string.d1
-rw-r--r--docs/cmdline-opts/form.d1
-rw-r--r--docs/cmdline-opts/ftp-account.d1
-rw-r--r--docs/cmdline-opts/ftp-alternative-to-user.d1
-rw-r--r--docs/cmdline-opts/ftp-create-dirs.d1
-rw-r--r--docs/cmdline-opts/ftp-method.d1
-rw-r--r--docs/cmdline-opts/ftp-pasv.d1
-rw-r--r--docs/cmdline-opts/ftp-port.d1
-rw-r--r--docs/cmdline-opts/ftp-pret.d1
-rw-r--r--docs/cmdline-opts/ftp-skip-pasv-ip.d3
-rw-r--r--docs/cmdline-opts/ftp-ssl-ccc-mode.d1
-rw-r--r--docs/cmdline-opts/ftp-ssl-ccc.d1
-rw-r--r--docs/cmdline-opts/ftp-ssl-control.d1
-rwxr-xr-xdocs/cmdline-opts/gen.pl66
-rw-r--r--docs/cmdline-opts/get.d1
-rw-r--r--docs/cmdline-opts/globoff.d1
-rw-r--r--docs/cmdline-opts/happy-eyeballs-timeout-ms.d1
-rw-r--r--docs/cmdline-opts/haproxy-protocol.d1
-rw-r--r--docs/cmdline-opts/head.d1
-rw-r--r--docs/cmdline-opts/header.d19
-rw-r--r--docs/cmdline-opts/help.d12
-rw-r--r--docs/cmdline-opts/hostpubmd5.d1
-rw-r--r--docs/cmdline-opts/hsts.d18
-rw-r--r--docs/cmdline-opts/http0.9.d1
-rw-r--r--docs/cmdline-opts/http1.0.d1
-rw-r--r--docs/cmdline-opts/http1.1.d1
-rw-r--r--docs/cmdline-opts/http2-prior-knowledge.d1
-rw-r--r--docs/cmdline-opts/http2.d1
-rw-r--r--docs/cmdline-opts/http3.d1
-rw-r--r--docs/cmdline-opts/ignore-content-length.d1
-rw-r--r--docs/cmdline-opts/include.d1
-rw-r--r--docs/cmdline-opts/insecure.d3
-rw-r--r--docs/cmdline-opts/interface.d1
-rw-r--r--docs/cmdline-opts/ipv4.d1
-rw-r--r--docs/cmdline-opts/ipv6.d1
-rw-r--r--docs/cmdline-opts/junk-session-cookies.d1
-rw-r--r--docs/cmdline-opts/keepalive-time.d1
-rw-r--r--docs/cmdline-opts/key-type.d1
-rw-r--r--docs/cmdline-opts/key.d1
-rw-r--r--docs/cmdline-opts/krb.d1
-rw-r--r--docs/cmdline-opts/libcurl.d1
-rw-r--r--docs/cmdline-opts/limit-rate.d1
-rw-r--r--docs/cmdline-opts/list-only.d1
-rw-r--r--docs/cmdline-opts/local-port.d1
-rw-r--r--docs/cmdline-opts/location-trusted.d1
-rw-r--r--docs/cmdline-opts/location.d1
-rw-r--r--docs/cmdline-opts/login-options.d1
-rw-r--r--docs/cmdline-opts/mail-auth.d1
-rw-r--r--docs/cmdline-opts/mail-from.d1
-rw-r--r--docs/cmdline-opts/mail-rcpt-allowfails.d1
-rw-r--r--docs/cmdline-opts/mail-rcpt.d1
-rw-r--r--docs/cmdline-opts/manual.d1
-rw-r--r--docs/cmdline-opts/max-filesize.d1
-rw-r--r--docs/cmdline-opts/max-redirs.d1
-rw-r--r--docs/cmdline-opts/max-time.d1
-rw-r--r--docs/cmdline-opts/metalink.d1
-rw-r--r--docs/cmdline-opts/negotiate.d1
-rw-r--r--docs/cmdline-opts/netrc-file.d1
-rw-r--r--docs/cmdline-opts/netrc-optional.d1
-rw-r--r--docs/cmdline-opts/netrc.d1
-rw-r--r--docs/cmdline-opts/next.d1
-rw-r--r--docs/cmdline-opts/no-alpn.d1
-rw-r--r--docs/cmdline-opts/no-buffer.d1
-rw-r--r--docs/cmdline-opts/no-keepalive.d1
-rw-r--r--docs/cmdline-opts/no-npn.d1
-rw-r--r--docs/cmdline-opts/no-progress-meter.d1
-rw-r--r--docs/cmdline-opts/no-sessionid.d1
-rw-r--r--docs/cmdline-opts/noproxy.d1
-rw-r--r--docs/cmdline-opts/ntlm-wb.d1
-rw-r--r--docs/cmdline-opts/ntlm.d1
-rw-r--r--docs/cmdline-opts/oauth2-bearer.d1
-rw-r--r--docs/cmdline-opts/output-dir.d19
-rw-r--r--docs/cmdline-opts/output.d1
-rw-r--r--docs/cmdline-opts/page-footer8
-rw-r--r--docs/cmdline-opts/page-header11
-rw-r--r--docs/cmdline-opts/parallel-immediate.d1
-rw-r--r--docs/cmdline-opts/parallel-max.d1
-rw-r--r--docs/cmdline-opts/parallel.d1
-rw-r--r--docs/cmdline-opts/pass.d1
-rw-r--r--docs/cmdline-opts/path-as-is.d1
-rw-r--r--docs/cmdline-opts/pinnedpubkey.d1
-rw-r--r--docs/cmdline-opts/post301.d1
-rw-r--r--docs/cmdline-opts/post302.d1
-rw-r--r--docs/cmdline-opts/post303.d1
-rw-r--r--docs/cmdline-opts/preproxy.d1
-rw-r--r--docs/cmdline-opts/progress-bar.d1
-rw-r--r--docs/cmdline-opts/proto-default.d1
-rw-r--r--docs/cmdline-opts/proto-redir.d1
-rw-r--r--docs/cmdline-opts/proto.d1
-rw-r--r--docs/cmdline-opts/proxy-anyauth.d1
-rw-r--r--docs/cmdline-opts/proxy-basic.d1
-rw-r--r--docs/cmdline-opts/proxy-cacert.d1
-rw-r--r--docs/cmdline-opts/proxy-capath.d1
-rw-r--r--docs/cmdline-opts/proxy-cert-type.d1
-rw-r--r--docs/cmdline-opts/proxy-cert.d1
-rw-r--r--docs/cmdline-opts/proxy-ciphers.d1
-rw-r--r--docs/cmdline-opts/proxy-crlfile.d1
-rw-r--r--docs/cmdline-opts/proxy-digest.d1
-rw-r--r--docs/cmdline-opts/proxy-header.d1
-rw-r--r--docs/cmdline-opts/proxy-insecure.d1
-rw-r--r--docs/cmdline-opts/proxy-key-type.d1
-rw-r--r--docs/cmdline-opts/proxy-key.d1
-rw-r--r--docs/cmdline-opts/proxy-negotiate.d1
-rw-r--r--docs/cmdline-opts/proxy-ntlm.d1
-rw-r--r--docs/cmdline-opts/proxy-pass.d1
-rw-r--r--docs/cmdline-opts/proxy-pinnedpubkey.d1
-rw-r--r--docs/cmdline-opts/proxy-service-name.d1
-rw-r--r--docs/cmdline-opts/proxy-ssl-allow-beast.d1
-rw-r--r--docs/cmdline-opts/proxy-tls13-ciphers.d3
-rw-r--r--docs/cmdline-opts/proxy-tlsauthtype.d1
-rw-r--r--docs/cmdline-opts/proxy-tlspassword.d1
-rw-r--r--docs/cmdline-opts/proxy-tlsuser.d1
-rw-r--r--docs/cmdline-opts/proxy-tlsv1.d1
-rw-r--r--docs/cmdline-opts/proxy-user.d1
-rw-r--r--docs/cmdline-opts/proxy.d1
-rw-r--r--docs/cmdline-opts/proxy1.0.d1
-rw-r--r--docs/cmdline-opts/proxytunnel.d1
-rw-r--r--docs/cmdline-opts/pubkey.d1
-rw-r--r--docs/cmdline-opts/quote.d9
-rw-r--r--docs/cmdline-opts/random-file.d1
-rw-r--r--docs/cmdline-opts/range.d4
-rw-r--r--docs/cmdline-opts/raw.d1
-rw-r--r--docs/cmdline-opts/referer.d1
-rw-r--r--docs/cmdline-opts/remote-header-name.d1
-rw-r--r--docs/cmdline-opts/remote-name-all.d1
-rw-r--r--docs/cmdline-opts/remote-name.d1
-rw-r--r--docs/cmdline-opts/remote-time.d1
-rw-r--r--docs/cmdline-opts/request-target.d1
-rw-r--r--docs/cmdline-opts/request.d1
-rw-r--r--docs/cmdline-opts/resolve.d1
-rw-r--r--docs/cmdline-opts/retry-all-errors.d1
-rw-r--r--docs/cmdline-opts/retry-connrefused.d1
-rw-r--r--docs/cmdline-opts/retry-delay.d1
-rw-r--r--docs/cmdline-opts/retry-max-time.d1
-rw-r--r--docs/cmdline-opts/retry.d1
-rw-r--r--docs/cmdline-opts/sasl-authzid.d1
-rw-r--r--docs/cmdline-opts/sasl-ir.d1
-rw-r--r--docs/cmdline-opts/service-name.d1
-rw-r--r--docs/cmdline-opts/show-error.d2
-rw-r--r--docs/cmdline-opts/silent.d3
-rw-r--r--docs/cmdline-opts/socks4.d1
-rw-r--r--docs/cmdline-opts/socks4a.d1
-rw-r--r--docs/cmdline-opts/socks5-basic.d1
-rw-r--r--docs/cmdline-opts/socks5-gssapi-nec.d1
-rw-r--r--docs/cmdline-opts/socks5-gssapi-service.d1
-rw-r--r--docs/cmdline-opts/socks5-gssapi.d1
-rw-r--r--docs/cmdline-opts/socks5-hostname.d1
-rw-r--r--docs/cmdline-opts/socks5.d1
-rw-r--r--docs/cmdline-opts/speed-limit.d1
-rw-r--r--docs/cmdline-opts/speed-time.d1
-rw-r--r--docs/cmdline-opts/ssl-allow-beast.d1
-rw-r--r--docs/cmdline-opts/ssl-no-revoke.d1
-rw-r--r--docs/cmdline-opts/ssl-reqd.d1
-rw-r--r--docs/cmdline-opts/ssl-revoke-best-effort.d1
-rw-r--r--docs/cmdline-opts/ssl.d1
-rw-r--r--docs/cmdline-opts/sslv2.d1
-rw-r--r--docs/cmdline-opts/sslv3.d1
-rw-r--r--docs/cmdline-opts/stderr.d1
-rw-r--r--docs/cmdline-opts/styled-output.d1
-rw-r--r--docs/cmdline-opts/suppress-connect-headers.d1
-rw-r--r--docs/cmdline-opts/tcp-fastopen.d1
-rw-r--r--docs/cmdline-opts/tcp-nodelay.d1
-rw-r--r--docs/cmdline-opts/telnet-option.d1
-rw-r--r--docs/cmdline-opts/tftp-blksize.d1
-rw-r--r--docs/cmdline-opts/tftp-no-options.d1
-rw-r--r--docs/cmdline-opts/time-cond.d1
-rw-r--r--docs/cmdline-opts/tls-max.d1
-rw-r--r--docs/cmdline-opts/tls13-ciphers.d3
-rw-r--r--docs/cmdline-opts/tlsauthtype.d1
-rw-r--r--docs/cmdline-opts/tlspassword.d1
-rw-r--r--docs/cmdline-opts/tlsuser.d1
-rw-r--r--docs/cmdline-opts/tlsv1.0.d1
-rw-r--r--docs/cmdline-opts/tlsv1.1.d1
-rw-r--r--docs/cmdline-opts/tlsv1.2.d1
-rw-r--r--docs/cmdline-opts/tlsv1.3.d1
-rw-r--r--docs/cmdline-opts/tlsv1.d1
-rw-r--r--docs/cmdline-opts/tr-encoding.d1
-rw-r--r--docs/cmdline-opts/trace-ascii.d1
-rw-r--r--docs/cmdline-opts/trace-time.d1
-rw-r--r--docs/cmdline-opts/trace.d1
-rw-r--r--docs/cmdline-opts/unix-socket.d1
-rw-r--r--docs/cmdline-opts/upload-file.d1
-rw-r--r--docs/cmdline-opts/url.d1
-rw-r--r--docs/cmdline-opts/use-ascii.d1
-rw-r--r--docs/cmdline-opts/user-agent.d1
-rw-r--r--docs/cmdline-opts/user.d1
-rw-r--r--docs/cmdline-opts/verbose.d1
-rw-r--r--docs/cmdline-opts/version.d3
-rw-r--r--docs/cmdline-opts/write-out.d5
-rw-r--r--docs/cmdline-opts/xattr.d1
-rw-r--r--docs/examples/.gitignore12
-rw-r--r--docs/examples/10-at-a-time.c4
-rw-r--r--docs/examples/Makefile.am4
-rw-r--r--docs/examples/Makefile.example2
-rw-r--r--docs/examples/Makefile.inc4
-rw-r--r--docs/examples/Makefile.m3232
-rw-r--r--docs/examples/Makefile.netware2
-rw-r--r--docs/examples/README.md (renamed from docs/examples/README)22
-rwxr-xr-xdocs/examples/adddocsref.pl4
-rw-r--r--docs/examples/altsvc.c4
-rw-r--r--docs/examples/anyauthput.c2
-rw-r--r--docs/examples/cacertinmem.c4
-rw-r--r--docs/examples/certinfo.c4
-rw-r--r--docs/examples/chkspeed.c4
-rw-r--r--docs/examples/cookie_interface.c4
-rw-r--r--docs/examples/debug.c4
-rw-r--r--docs/examples/ephiperfifo.c2
-rw-r--r--docs/examples/evhiperfifo.c4
-rw-r--r--docs/examples/externalsocket.c4
-rw-r--r--docs/examples/fileupload.c4
-rw-r--r--docs/examples/ftp-wildcard.c4
-rw-r--r--docs/examples/ftpget.c4
-rw-r--r--docs/examples/ftpgetinfo.c6
-rw-r--r--docs/examples/ftpgetresp.c4
-rw-r--r--docs/examples/ftpsget.c4
-rw-r--r--docs/examples/ftpupload.c4
-rw-r--r--docs/examples/ftpuploadfrommem.c4
-rw-r--r--docs/examples/ftpuploadresume.c4
-rw-r--r--docs/examples/getinfo.c4
-rw-r--r--docs/examples/getinmemory.c4
-rw-r--r--docs/examples/getredirect.c4
-rw-r--r--docs/examples/ghiper.c4
-rw-r--r--docs/examples/hiperfifo.c4
-rw-r--r--docs/examples/href_extractor.c4
-rw-r--r--docs/examples/htmltidy.c4
-rw-r--r--docs/examples/htmltitle.cpp4
-rw-r--r--docs/examples/http-post.c4
-rw-r--r--docs/examples/http2-download.c2
-rw-r--r--docs/examples/http2-pushinmemory.c4
-rw-r--r--docs/examples/http2-serverpush.c4
-rw-r--r--docs/examples/http2-upload.c2
-rw-r--r--docs/examples/http3-present.c4
-rw-r--r--docs/examples/http3.c4
-rw-r--r--docs/examples/httpcustomheader.c4
-rw-r--r--docs/examples/httpput-postfields.c101
-rw-r--r--docs/examples/httpput.c9
-rw-r--r--docs/examples/https.c4
-rw-r--r--docs/examples/imap-append.c4
-rw-r--r--docs/examples/imap-authzid.c4
-rw-r--r--docs/examples/imap-copy.c4
-rw-r--r--docs/examples/imap-create.c4
-rw-r--r--docs/examples/imap-delete.c4
-rw-r--r--docs/examples/imap-examine.c4
-rw-r--r--docs/examples/imap-fetch.c4
-rw-r--r--docs/examples/imap-list.c4
-rw-r--r--docs/examples/imap-lsub.c4
-rw-r--r--docs/examples/imap-multi.c4
-rw-r--r--docs/examples/imap-noop.c4
-rw-r--r--docs/examples/imap-search.c4
-rw-r--r--docs/examples/imap-ssl.c4
-rw-r--r--docs/examples/imap-store.c4
-rw-r--r--docs/examples/imap-tls.c4
-rw-r--r--docs/examples/makefile.dj2
-rw-r--r--docs/examples/multi-app.c4
-rw-r--r--docs/examples/multi-debugcallback.c4
-rw-r--r--docs/examples/multi-double.c4
-rw-r--r--docs/examples/multi-event.c2
-rw-r--r--docs/examples/multi-formadd.c4
-rw-r--r--docs/examples/multi-poll.c4
-rw-r--r--docs/examples/multi-post.c4
-rw-r--r--docs/examples/multi-single.c4
-rw-r--r--docs/examples/multi-uv.c2
-rw-r--r--docs/examples/multithread.c6
-rw-r--r--docs/examples/opensslthreadlock.c4
-rw-r--r--docs/examples/parseurl.c4
-rw-r--r--docs/examples/persistent.c4
-rw-r--r--docs/examples/pop3-authzid.c4
-rw-r--r--docs/examples/pop3-dele.c4
-rw-r--r--docs/examples/pop3-list.c4
-rw-r--r--docs/examples/pop3-multi.c4
-rw-r--r--docs/examples/pop3-noop.c4
-rw-r--r--docs/examples/pop3-retr.c4
-rw-r--r--docs/examples/pop3-ssl.c4
-rw-r--r--docs/examples/pop3-stat.c4
-rw-r--r--docs/examples/pop3-tls.c4
-rw-r--r--docs/examples/pop3-top.c4
-rw-r--r--docs/examples/pop3-uidl.c4
-rw-r--r--docs/examples/post-callback.c4
-rw-r--r--docs/examples/postinmemory.c4
-rw-r--r--docs/examples/postit2-formadd.c4
-rw-r--r--docs/examples/postit2.c4
-rw-r--r--docs/examples/progressfunc.c4
-rw-r--r--docs/examples/resolve.c4
-rw-r--r--docs/examples/sampleconv.c4
-rw-r--r--docs/examples/sendrecv.c4
-rw-r--r--docs/examples/sepheaders.c4
-rw-r--r--docs/examples/sessioninfo.c2
-rw-r--r--docs/examples/sftpget.c4
-rw-r--r--docs/examples/sftpuploadresume.c4
-rw-r--r--docs/examples/shared-connection-cache.c6
-rw-r--r--docs/examples/simple.c4
-rw-r--r--docs/examples/simplepost.c4
-rw-r--r--docs/examples/simplessl.c4
-rw-r--r--docs/examples/smooth-gtk-thread.c4
-rw-r--r--docs/examples/smtp-authzid.c4
-rw-r--r--docs/examples/smtp-expn.c4
-rw-r--r--docs/examples/smtp-mail.c4
-rw-r--r--docs/examples/smtp-mime.c4
-rw-r--r--docs/examples/smtp-multi.c4
-rw-r--r--docs/examples/smtp-ssl.c4
-rw-r--r--docs/examples/smtp-tls.c4
-rw-r--r--docs/examples/smtp-vrfy.c4
-rw-r--r--docs/examples/sslbackend.c8
-rw-r--r--docs/examples/synctime.c4
-rw-r--r--docs/examples/threaded-shared-conn.c4
-rw-r--r--docs/examples/threaded-ssl.c4
-rw-r--r--docs/examples/url2file.c4
-rw-r--r--docs/examples/urlapi.c4
-rw-r--r--docs/examples/usercertinmem.c4
-rwxr-xr-xdocs/examples/version-check.pl2
-rw-r--r--docs/examples/xmlstream.c4
-rw-r--r--docs/gnurl-config.12
-rw-r--r--docs/libcurl/CMakeLists.txt2
-rw-r--r--docs/libcurl/Makefile.am2
-rw-r--r--docs/libcurl/Makefile.inc169
-rw-r--r--docs/libcurl/curl_easy_option_by_id.346
-rw-r--r--docs/libcurl/curl_easy_option_by_name.344
-rw-r--r--docs/libcurl/curl_easy_option_next.374
-rw-r--r--docs/libcurl/gnurl_easy_cleanup.36
-rw-r--r--docs/libcurl/gnurl_easy_duphandle.34
-rw-r--r--docs/libcurl/gnurl_easy_escape.35
-rw-r--r--docs/libcurl/gnurl_easy_getinfo.35
-rw-r--r--docs/libcurl/gnurl_easy_init.34
-rw-r--r--docs/libcurl/gnurl_easy_pause.34
-rw-r--r--docs/libcurl/gnurl_easy_perform.34
-rw-r--r--docs/libcurl/gnurl_easy_recv.34
-rw-r--r--docs/libcurl/gnurl_easy_reset.32
-rw-r--r--docs/libcurl/gnurl_easy_send.34
-rw-r--r--docs/libcurl/gnurl_easy_setopt.324
-rw-r--r--docs/libcurl/gnurl_easy_strerror.32
-rw-r--r--docs/libcurl/gnurl_easy_unescape.32
-rw-r--r--docs/libcurl/gnurl_easy_upkeep.34
-rw-r--r--docs/libcurl/gnurl_escape.32
-rw-r--r--docs/libcurl/gnurl_formadd.32
-rw-r--r--docs/libcurl/gnurl_formfree.34
-rw-r--r--docs/libcurl/gnurl_formget.34
-rw-r--r--docs/libcurl/gnurl_free.34
-rw-r--r--docs/libcurl/gnurl_getdate.34
-rw-r--r--docs/libcurl/gnurl_getenv.32
-rw-r--r--docs/libcurl/gnurl_global_cleanup.34
-rw-r--r--docs/libcurl/gnurl_global_init.32
-rw-r--r--docs/libcurl/gnurl_global_init_mem.34
-rw-r--r--docs/libcurl/gnurl_global_sslset.32
-rw-r--r--docs/libcurl/gnurl_mime_addpart.34
-rw-r--r--docs/libcurl/gnurl_mime_data.32
-rw-r--r--docs/libcurl/gnurl_mime_data_cb.34
-rw-r--r--docs/libcurl/gnurl_mime_encoder.32
-rw-r--r--docs/libcurl/gnurl_mime_filedata.32
-rw-r--r--docs/libcurl/gnurl_mime_filename.32
-rw-r--r--docs/libcurl/gnurl_mime_free.34
-rw-r--r--docs/libcurl/gnurl_mime_headers.36
-rw-r--r--docs/libcurl/gnurl_mime_init.36
-rw-r--r--docs/libcurl/gnurl_mime_name.32
-rw-r--r--docs/libcurl/gnurl_mime_subparts.34
-rw-r--r--docs/libcurl/gnurl_mime_type.32
-rw-r--r--docs/libcurl/gnurl_mprintf.34
-rw-r--r--docs/libcurl/gnurl_multi_add_handle.34
-rw-r--r--docs/libcurl/gnurl_multi_assign.32
-rw-r--r--docs/libcurl/gnurl_multi_cleanup.34
-rw-r--r--docs/libcurl/gnurl_multi_fdset.34
-rw-r--r--docs/libcurl/gnurl_multi_info_read.32
-rw-r--r--docs/libcurl/gnurl_multi_init.32
-rw-r--r--docs/libcurl/gnurl_multi_perform.32
-rw-r--r--docs/libcurl/gnurl_multi_poll.34
-rw-r--r--docs/libcurl/gnurl_multi_remove_handle.34
-rw-r--r--docs/libcurl/gnurl_multi_setopt.34
-rw-r--r--docs/libcurl/gnurl_multi_socket.34
-rw-r--r--docs/libcurl/gnurl_multi_socket_action.34
-rw-r--r--docs/libcurl/gnurl_multi_strerror.32
-rw-r--r--docs/libcurl/gnurl_multi_timeout.32
-rw-r--r--docs/libcurl/gnurl_multi_wait.34
-rw-r--r--docs/libcurl/gnurl_multi_wakeup.34
-rw-r--r--docs/libcurl/gnurl_share_cleanup.34
-rw-r--r--docs/libcurl/gnurl_share_init.32
-rw-r--r--docs/libcurl/gnurl_share_setopt.32
-rw-r--r--docs/libcurl/gnurl_share_strerror.32
-rw-r--r--docs/libcurl/gnurl_slist_append.34
-rw-r--r--docs/libcurl/gnurl_slist_free_all.34
-rw-r--r--docs/libcurl/gnurl_strequal.34
-rw-r--r--docs/libcurl/gnurl_unescape.32
-rw-r--r--docs/libcurl/gnurl_url.34
-rw-r--r--docs/libcurl/gnurl_url_cleanup.34
-rw-r--r--docs/libcurl/gnurl_url_dup.34
-rw-r--r--docs/libcurl/gnurl_url_get.34
-rw-r--r--docs/libcurl/gnurl_url_set.34
-rw-r--r--docs/libcurl/gnurl_version.32
-rw-r--r--docs/libcurl/gnurl_version_info.38
-rw-r--r--docs/libcurl/libgnurl-easy.32
-rw-r--r--docs/libcurl/libgnurl-env.36
-rw-r--r--docs/libcurl/libgnurl-errors.32
-rw-r--r--docs/libcurl/libgnurl-multi.32
-rw-r--r--docs/libcurl/libgnurl-security.36
-rw-r--r--docs/libcurl/libgnurl-share.34
-rw-r--r--docs/libcurl/libgnurl-thread.34
-rw-r--r--docs/libcurl/libgnurl-tutorial.34
-rw-r--r--docs/libcurl/libgnurl-url.34
-rw-r--r--docs/libcurl/libgnurl.32
-rw-r--r--docs/libcurl/libgnurl.m42
-rwxr-xr-xdocs/libcurl/mksymbolsmanpage.pl4
-rw-r--r--docs/libcurl/opts/CMakeLists.txt2
-rw-r--r--docs/libcurl/opts/CURLINFO_PROXY_ERROR.3104
-rw-r--r--docs/libcurl/opts/CURLOPT_HSTS.381
-rw-r--r--docs/libcurl/opts/CURLOPT_HSTSREADDATA.366
-rw-r--r--docs/libcurl/opts/CURLOPT_HSTSREADFUNCTION.381
-rw-r--r--docs/libcurl/opts/CURLOPT_HSTSWRITEDATA.366
-rw-r--r--docs/libcurl/opts/CURLOPT_HSTSWRITEFUNCTION.379
-rw-r--r--docs/libcurl/opts/CURLOPT_HSTS_CTRL.373
-rw-r--r--docs/libcurl/opts/CURLOPT_SSL_EC_CURVES.354
-rw-r--r--docs/libcurl/opts/GNURLINFO_ACTIVESOCKET.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_APPCONNECT_TIME.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_APPCONNECT_TIME_T.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_CERTINFO.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_CONDITION_UNMET.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_CONNECT_TIME.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_CONNECT_TIME_T.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_DOWNLOAD.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_DOWNLOAD_T.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_UPLOAD.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_UPLOAD_T.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_CONTENT_TYPE.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_COOKIELIST.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_EFFECTIVE_METHOD.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_EFFECTIVE_URL.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_FILETIME.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_FILETIME_T.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_FTP_ENTRY_PATH.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_HEADER_SIZE.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_HTTPAUTH_AVAIL.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_HTTP_CONNECTCODE.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_HTTP_VERSION.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_LASTSOCKET.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_LOCAL_IP.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_LOCAL_PORT.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_NAMELOOKUP_TIME.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_NAMELOOKUP_TIME_T.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_NUM_CONNECTS.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_OS_ERRNO.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_PRETRANSFER_TIME.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_PRETRANSFER_TIME_T.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_PRIMARY_IP.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_PRIMARY_PORT.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_PRIVATE.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_PROTOCOL.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_PROXYAUTH_AVAIL.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_PROXY_SSL_VERIFYRESULT.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_REDIRECT_COUNT.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_REDIRECT_TIME.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_REDIRECT_TIME_T.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_REDIRECT_URL.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_REQUEST_SIZE.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_RESPONSE_CODE.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_RETRY_AFTER.36
-rw-r--r--docs/libcurl/opts/GNURLINFO_RTSP_CLIENT_CSEQ.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_RTSP_CSEQ_RECV.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_RTSP_SERVER_CSEQ.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_RTSP_SESSION_ID.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_SCHEME.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_SIZE_DOWNLOAD.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_SIZE_DOWNLOAD_T.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_SIZE_UPLOAD.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_SIZE_UPLOAD_T.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_SPEED_DOWNLOAD.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_SPEED_DOWNLOAD_T.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_SPEED_UPLOAD.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_SPEED_UPLOAD_T.34
-rw-r--r--docs/libcurl/opts/GNURLINFO_SSL_ENGINES.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_SSL_VERIFYRESULT.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_STARTTRANSFER_TIME.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_STARTTRANSFER_TIME_T.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_TLS_SESSION.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_TLS_SSL_PTR.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_TOTAL_TIME.32
-rw-r--r--docs/libcurl/opts/GNURLINFO_TOTAL_TIME_T.32
-rw-r--r--docs/libcurl/opts/GNURLMOPT_CHUNK_LENGTH_PENALTY_SIZE.32
-rw-r--r--docs/libcurl/opts/GNURLMOPT_CONTENT_LENGTH_PENALTY_SIZE.32
-rw-r--r--docs/libcurl/opts/GNURLMOPT_MAXCONNECTS.32
-rw-r--r--docs/libcurl/opts/GNURLMOPT_MAX_CONCURRENT_STREAMS.32
-rw-r--r--docs/libcurl/opts/GNURLMOPT_MAX_HOST_CONNECTIONS.32
-rw-r--r--docs/libcurl/opts/GNURLMOPT_MAX_PIPELINE_LENGTH.32
-rw-r--r--docs/libcurl/opts/GNURLMOPT_MAX_TOTAL_CONNECTIONS.32
-rw-r--r--docs/libcurl/opts/GNURLMOPT_PIPELINING.32
-rw-r--r--docs/libcurl/opts/GNURLMOPT_PIPELINING_SERVER_BL.32
-rw-r--r--docs/libcurl/opts/GNURLMOPT_PIPELINING_SITE_BL.32
-rw-r--r--docs/libcurl/opts/GNURLMOPT_PUSHDATA.32
-rw-r--r--docs/libcurl/opts/GNURLMOPT_PUSHFUNCTION.32
-rw-r--r--docs/libcurl/opts/GNURLMOPT_SOCKETDATA.32
-rw-r--r--docs/libcurl/opts/GNURLMOPT_SOCKETFUNCTION.32
-rw-r--r--docs/libcurl/opts/GNURLMOPT_TIMERDATA.32
-rw-r--r--docs/libcurl/opts/GNURLMOPT_TIMERFUNCTION.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_ABSTRACT_UNIX_SOCKET.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_ACCEPTTIMEOUT_MS.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_ACCEPT_ENCODING.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_ADDRESS_SCOPE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_ALTSVC.39
-rw-r--r--docs/libcurl/opts/GNURLOPT_ALTSVC_CTRL.312
-rw-r--r--docs/libcurl/opts/GNURLOPT_APPEND.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_AUTOREFERER.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_BUFFERSIZE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_CAINFO.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_CAPATH.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_CERTINFO.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_CHUNK_BGN_FUNCTION.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_CHUNK_DATA.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_CHUNK_END_FUNCTION.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_CLOSESOCKETDATA.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_CLOSESOCKETFUNCTION.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_CONNECTTIMEOUT.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_CONNECTTIMEOUT_MS.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_CONNECT_ONLY.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_CONNECT_TO.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_CONV_FROM_NETWORK_FUNCTION.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_CONV_FROM_UTF8_FUNCTION.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_CONV_TO_NETWORK_FUNCTION.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_COOKIE.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_COOKIEFILE.36
-rw-r--r--docs/libcurl/opts/GNURLOPT_COOKIEJAR.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_COOKIELIST.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_COOKIESESSION.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_COPYPOSTFIELDS.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_CRLF.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_CRLFILE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_CURLU.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_CUSTOMREQUEST.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_DEBUGDATA.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_DEBUGFUNCTION.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_DEFAULT_PROTOCOL.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_DIRLISTONLY.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_DISALLOW_USERNAME_IN_URL.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_DNS_CACHE_TIMEOUT.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_DNS_INTERFACE.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_DNS_LOCAL_IP4.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_DNS_LOCAL_IP6.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_DNS_SERVERS.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_DNS_SHUFFLE_ADDRESSES.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_DNS_USE_GLOBAL_CACHE.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_DOH_URL.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_EGDSOCKET.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_ERRORBUFFER.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_EXPECT_100_TIMEOUT_MS.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_FAILONERROR.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_FILETIME.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_FNMATCH_DATA.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_FNMATCH_FUNCTION.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_FOLLOWLOCATION.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_FORBID_REUSE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_FRESH_CONNECT.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_FTPPORT.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_FTPSSLAUTH.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_FTP_ACCOUNT.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_FTP_ALTERNATIVE_TO_USER.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_FTP_CREATE_MISSING_DIRS.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_FTP_FILEMETHOD.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_FTP_RESPONSE_TIMEOUT.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_FTP_SKIP_PASV_IP.310
-rw-r--r--docs/libcurl/opts/GNURLOPT_FTP_SSL_CCC.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_FTP_USE_EPRT.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_FTP_USE_EPSV.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_FTP_USE_PRET.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_GSSAPI_DELEGATION.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_HAPROXYPROTOCOL.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_HEADER.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_HEADERDATA.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_HEADERFUNCTION.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_HEADEROPT.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_HTTP09_ALLOWED.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_HTTP200ALIASES.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_HTTPAUTH.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_HTTPGET.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_HTTPHEADER.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_HTTPPOST.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_HTTPPROXYTUNNEL.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_HTTP_CONTENT_DECODING.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_HTTP_TRANSFER_DECODING.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_HTTP_VERSION.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_IGNORE_CONTENT_LENGTH.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_INFILESIZE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_INFILESIZE_LARGE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_INTERFACE.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_INTERLEAVEDATA.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_INTERLEAVEFUNCTION.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_IOCTLDATA.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_IOCTLFUNCTION.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_IPRESOLVE.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_ISSUERCERT.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_ISSUERCERT_BLOB.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_KEEP_SENDING_ON_ERROR.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_KEYPASSWD.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_KRBLEVEL.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_LOCALPORT.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_LOCALPORTRANGE.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_LOGIN_OPTIONS.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_LOW_SPEED_LIMIT.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_LOW_SPEED_TIME.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_MAIL_AUTH.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_MAIL_FROM.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_MAIL_RCPT.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_MAIL_RCPT_ALLLOWFAILS.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_MAXAGE_CONN.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_MAXCONNECTS.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_MAXFILESIZE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_MAXFILESIZE_LARGE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_MAXREDIRS.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_MAX_RECV_SPEED_LARGE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_MAX_SEND_SPEED_LARGE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_MIMEPOST.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_NETRC.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_NETRC_FILE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_NEW_DIRECTORY_PERMS.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_NEW_FILE_PERMS.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_NOBODY.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_NOPROGRESS.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_NOPROXY.38
-rw-r--r--docs/libcurl/opts/GNURLOPT_NOSIGNAL.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_OPENSOCKETDATA.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_OPENSOCKETFUNCTION.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PASSWORD.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_PATH_AS_IS.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_PINNEDPUBLICKEY.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PIPEWAIT.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PORT.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_POST.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_POSTFIELDS.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_POSTFIELDSIZE.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_POSTFIELDSIZE_LARGE.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_POSTQUOTE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_POSTREDIR.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_PREQUOTE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PRE_PROXY.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_PRIVATE.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROGRESSDATA.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROGRESSFUNCTION.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROTOCOLS.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXYAUTH.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXYHEADER.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXYPASSWORD.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXYPORT.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXYTYPE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXYUSERNAME.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXYUSERPWD.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_CAINFO.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_CAPATH.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_CRLFILE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_ISSUERCERT.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_ISSUERCERT_BLOB.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_KEYPASSWD.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_PINNEDPUBLICKEY.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_SERVICE_NAME.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_SSLCERT.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_SSLCERTTYPE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_SSLCERT_BLOB.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_SSLKEY.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_SSLKEYTYPE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_SSLKEY_BLOB.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_SSLVERSION.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_SSL_CIPHER_LIST.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_SSL_OPTIONS.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_SSL_VERIFYHOST.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_SSL_VERIFYPEER.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_TLS13_CIPHERS.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_TLSAUTH_PASSWORD.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_TLSAUTH_TYPE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_TLSAUTH_USERNAME.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PROXY_TRANSFER_MODE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_PUT.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_QUOTE.310
-rw-r--r--docs/libcurl/opts/GNURLOPT_RANDOM_FILE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_RANGE.36
-rw-r--r--docs/libcurl/opts/GNURLOPT_READDATA.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_READFUNCTION.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_REDIR_PROTOCOLS.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_REFERER.36
-rw-r--r--docs/libcurl/opts/GNURLOPT_REQUEST_TARGET.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_RESOLVE.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_RESOLVER_START_DATA.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_RESOLVER_START_FUNCTION.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_RESUME_FROM.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_RESUME_FROM_LARGE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_RTSP_CLIENT_CSEQ.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_RTSP_REQUEST.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_RTSP_SERVER_CSEQ.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_RTSP_SESSION_ID.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_RTSP_STREAM_URI.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_RTSP_TRANSPORT.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SASL_AUTHZID.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SASL_IR.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SEEKDATA.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SEEKFUNCTION.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SERVICE_NAME.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SHARE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SOCKOPTDATA.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_SOCKOPTFUNCTION.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SOCKS5_AUTH.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SOCKS5_GSSAPI_NEC.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SOCKS5_GSSAPI_SERVICE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSH_AUTH_TYPES.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSH_COMPRESSION.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSH_HOST_PUBLIC_KEY_MD5.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSH_KEYDATA.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSH_KEYFUNCTION.313
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSH_KNOWNHOSTS.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSH_PRIVATE_KEYFILE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSH_PUBLIC_KEYFILE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSLCERT.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSLCERTTYPE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSLCERT_BLOB.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSLENGINE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSLENGINE_DEFAULT.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSLKEY.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSLKEYTYPE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSLKEY_BLOB.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSLVERSION.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSL_CIPHER_LIST.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSL_CTX_DATA.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSL_CTX_FUNCTION.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSL_ENABLE_ALPN.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSL_ENABLE_NPN.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSL_FALSESTART.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSL_OPTIONS.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSL_SESSIONID_CACHE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSL_VERIFYHOST.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSL_VERIFYPEER.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SSL_VERIFYSTATUS.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_STDERR.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_STREAM_DEPENDS.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_STREAM_DEPENDS_E.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_STREAM_WEIGHT.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_SUPPRESS_CONNECT_HEADERS.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_TCP_FASTOPEN.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_TCP_KEEPALIVE.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_TCP_KEEPIDLE.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_TCP_KEEPINTVL.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_TCP_NODELAY.36
-rw-r--r--docs/libcurl/opts/GNURLOPT_TELNETOPTIONS.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_TFTP_BLKSIZE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_TFTP_NO_OPTIONS.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_TIMECONDITION.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_TIMEOUT.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_TIMEOUT_MS.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_TIMEVALUE.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_TIMEVALUE_LARGE.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_TLS13_CIPHERS.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_TLSAUTH_PASSWORD.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_TLSAUTH_TYPE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_TLSAUTH_USERNAME.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_TRAILERDATA.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_TRAILERFUNCTION.36
-rw-r--r--docs/libcurl/opts/GNURLOPT_TRANSFERTEXT.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_TRANSFER_ENCODING.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_UNIX_SOCKET_PATH.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_UNRESTRICTED_AUTH.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_UPKEEP_INTERVAL_MS.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_UPLOAD.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_UPLOAD_BUFFERSIZE.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_URL.321
-rw-r--r--docs/libcurl/opts/GNURLOPT_USERAGENT.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_USERNAME.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_USERPWD.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_USE_SSL.32
-rw-r--r--docs/libcurl/opts/GNURLOPT_VERBOSE.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_WILDCARDMATCH.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_WRITEDATA.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_WRITEFUNCTION.39
-rw-r--r--docs/libcurl/opts/GNURLOPT_XFERINFODATA.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_XFERINFOFUNCTION.34
-rw-r--r--docs/libcurl/opts/GNURLOPT_XOAUTH2_BEARER.32
-rw-r--r--docs/libcurl/opts/Makefile.am4
-rw-r--r--docs/libcurl/opts/Makefile.inc728
-rw-r--r--docs/libcurl/opts/template.32
-rw-r--r--docs/libcurl/symbols-in-versions78
-rwxr-xr-xdocs/libcurl/symbols.pl2
-rw-r--r--docs/mk-ca-bundle.16
-rw-r--r--docs/options-in-versions3
-rw-r--r--gnurl-config.in2
-rw-r--r--include/Makefile.am4
-rw-r--r--include/README18
-rw-r--r--include/README.md14
-rw-r--r--include/gnurl/Makefile.am6
-rw-r--r--include/gnurl/curl.h193
-rw-r--r--include/gnurl/curlver.h8
-rw-r--r--include/gnurl/easy.h2
-rw-r--r--include/gnurl/mprintf.h4
-rw-r--r--include/gnurl/multi.h2
-rw-r--r--include/gnurl/options.h68
-rw-r--r--include/gnurl/stdcheaders.h4
-rw-r--r--include/gnurl/system.h4
-rw-r--r--include/gnurl/typecheck-gcc.h8
-rw-r--r--include/gnurl/urlapi.h4
-rw-r--r--lib/.gitattributes2
-rw-r--r--lib/CMakeLists.txt17
-rw-r--r--lib/Makefile.Watcom274
-rw-r--r--lib/Makefile.am9
-rw-r--r--lib/Makefile.inc10
-rw-r--r--lib/Makefile.m3240
-rw-r--r--lib/Makefile.netware6
-rw-r--r--lib/Makefile.vxworks2
-rw-r--r--lib/altsvc.c36
-rw-r--r--lib/altsvc.h13
-rw-r--r--lib/amigaos.c4
-rw-r--r--lib/amigaos.h4
-rw-r--r--lib/arpa_telnet.h4
-rw-r--r--lib/asyn-ares.c29
-rw-r--r--lib/asyn-thread.c26
-rw-r--r--lib/asyn.h2
-rw-r--r--lib/base64.c7
-rwxr-xr-xlib/checksrc.pl31
-rw-r--r--lib/config-amigaos.h6
-rw-r--r--lib/config-dos.h2
-rw-r--r--lib/config-mac.h4
-rw-r--r--lib/config-os400.h5
-rw-r--r--lib/config-plan9.h4
-rw-r--r--lib/config-riscos.h2
-rw-r--r--lib/config-symbian.h793
-rw-r--r--lib/config-tpf.h4
-rw-r--r--lib/config-vxworks.h2
-rw-r--r--lib/config-win32.h2
-rw-r--r--lib/config-win32ce.h4
-rw-r--r--lib/conncache.c36
-rw-r--r--lib/conncache.h6
-rw-r--r--lib/connect.c133
-rw-r--r--lib/connect.h4
-rw-r--r--lib/content_encoding.c6
-rw-r--r--lib/content_encoding.h2
-rw-r--r--lib/cookie.c4
-rw-r--r--lib/cookie.h4
-rw-r--r--lib/curl_addrinfo.c2
-rw-r--r--lib/curl_addrinfo.h2
-rw-r--r--lib/curl_base64.h4
-rw-r--r--lib/curl_config.h.cmake20
-rw-r--r--lib/curl_ctype.c4
-rw-r--r--lib/curl_ctype.h4
-rw-r--r--lib/curl_des.c4
-rw-r--r--lib/curl_des.h4
-rw-r--r--lib/curl_endian.c4
-rw-r--r--lib/curl_endian.h4
-rw-r--r--lib/curl_fnmatch.c4
-rw-r--r--lib/curl_fnmatch.h4
-rw-r--r--lib/curl_get_line.c9
-rw-r--r--lib/curl_get_line.h4
-rw-r--r--lib/curl_gethostname.c6
-rw-r--r--lib/curl_gethostname.h6
-rw-r--r--lib/curl_gssapi.c4
-rw-r--r--lib/curl_gssapi.h4
-rw-r--r--lib/curl_hmac.h2
-rw-r--r--lib/curl_krb5.h (renamed from lib/curl_sec.h)14
-rw-r--r--lib/curl_ldap.h4
-rw-r--r--lib/curl_md4.h2
-rw-r--r--lib/curl_md5.h2
-rw-r--r--lib/curl_memory.h4
-rw-r--r--lib/curl_memrchr.c4
-rw-r--r--lib/curl_memrchr.h4
-rw-r--r--lib/curl_multibyte.c2
-rw-r--r--lib/curl_multibyte.h2
-rw-r--r--lib/curl_ntlm_core.c18
-rw-r--r--lib/curl_ntlm_core.h10
-rw-r--r--lib/curl_ntlm_wb.c2
-rw-r--r--lib/curl_ntlm_wb.h4
-rw-r--r--lib/curl_path.c6
-rw-r--r--lib/curl_path.h4
-rw-r--r--lib/curl_printf.h4
-rw-r--r--lib/curl_range.c4
-rw-r--r--lib/curl_range.h4
-rw-r--r--lib/curl_rtmp.c10
-rw-r--r--lib/curl_rtmp.h4
-rw-r--r--lib/curl_sasl.c2
-rw-r--r--lib/curl_sasl.h4
-rw-r--r--lib/curl_setup.h36
-rw-r--r--lib/curl_setup_once.h2
-rw-r--r--lib/curl_sha256.h2
-rw-r--r--lib/curl_sspi.c2
-rw-r--r--lib/curl_sspi.h4
-rw-r--r--lib/curl_threads.c8
-rw-r--r--lib/curl_threads.h4
-rw-r--r--lib/curlx.h2
-rw-r--r--lib/dict.c97
-rw-r--r--lib/dict.h4
-rw-r--r--lib/doh.c11
-rw-r--r--lib/doh.h2
-rw-r--r--lib/dotdot.c2
-rw-r--r--lib/dotdot.h4
-rw-r--r--lib/dynbuf.c50
-rw-r--r--lib/dynbuf.h27
-rw-r--r--lib/easy.c46
-rw-r--r--lib/easygetopt.c96
-rw-r--r--lib/easyif.h2
-rw-r--r--lib/easyoptions.c353
-rw-r--r--lib/easyoptions.h35
-rw-r--r--lib/escape.c4
-rw-r--r--lib/escape.h2
-rw-r--r--lib/file.c30
-rw-r--r--lib/file.h4
-rw-r--r--lib/fileinfo.c4
-rw-r--r--lib/fileinfo.h6
-rw-r--r--lib/firefox-db2pem.sh2
-rw-r--r--lib/formdata.c2
-rw-r--r--lib/formdata.h2
-rw-r--r--lib/ftp.c670
-rw-r--r--lib/ftp.h3
-rw-r--r--lib/ftplistparser.c10
-rw-r--r--lib/ftplistparser.h4
-rw-r--r--lib/getenv.c2
-rw-r--r--lib/getinfo.c5
-rw-r--r--lib/getinfo.h4
-rw-r--r--lib/gopher.c9
-rw-r--r--lib/gopher.h4
-rw-r--r--lib/hash.c84
-rw-r--r--lib/hash.h50
-rw-r--r--lib/hmac.c2
-rw-r--r--lib/hostasyn.c2
-rw-r--r--lib/hostcheck.c4
-rw-r--r--lib/hostcheck.h4
-rw-r--r--lib/hostip.c8
-rw-r--r--lib/hostip.h10
-rw-r--r--lib/hostip4.c2
-rw-r--r--lib/hostip6.c2
-rw-r--r--lib/hostsyn.c4
-rw-r--r--lib/hsts.c522
-rw-r--r--lib/hsts.h65
-rw-r--r--lib/http.c83
-rw-r--r--lib/http.h2
-rw-r--r--lib/http2.c178
-rw-r--r--lib/http2.h2
-rw-r--r--lib/http_chunks.c2
-rw-r--r--lib/http_chunks.h4
-rw-r--r--lib/http_digest.c2
-rw-r--r--lib/http_digest.h2
-rw-r--r--lib/http_negotiate.c2
-rw-r--r--lib/http_negotiate.h2
-rw-r--r--lib/http_ntlm.c2
-rw-r--r--lib/http_ntlm.h2
-rw-r--r--lib/http_proxy.c32
-rw-r--r--lib/http_proxy.h2
-rw-r--r--lib/idn_win32.c2
-rw-r--r--lib/if2ip.c2
-rw-r--r--lib/if2ip.h4
-rw-r--r--lib/imap.c65
-rw-r--r--lib/imap.h7
-rw-r--r--lib/inet_ntop.h4
-rw-r--r--lib/inet_pton.c4
-rw-r--r--lib/inet_pton.h4
-rw-r--r--lib/krb5.c595
-rw-r--r--lib/ldap.c72
-rw-r--r--lib/libcurl.rc8
-rw-r--r--lib/libgnurl.plist2
-rw-r--r--lib/llist.c14
-rw-r--r--lib/llist.h30
-rw-r--r--lib/makefile.amiga2
-rw-r--r--lib/makefile.dj2
-rw-r--r--lib/md4.c2
-rw-r--r--lib/md5.c2
-rw-r--r--lib/memdebug.c53
-rw-r--r--lib/memdebug.h2
-rw-r--r--lib/mime.c2
-rw-r--r--lib/mime.h2
-rwxr-xr-xlib/mk-ca-bundle.pl2
-rwxr-xr-xlib/mk-ca-bundle.vbs2
-rw-r--r--lib/mprintf.c57
-rw-r--r--lib/mqtt.c40
-rw-r--r--lib/mqtt.h4
-rw-r--r--lib/multi.c94
-rw-r--r--lib/multihandle.h16
-rw-r--r--lib/multiif.h2
-rw-r--r--lib/netrc.c4
-rw-r--r--lib/netrc.h4
-rw-r--r--lib/non-ascii.c4
-rw-r--r--lib/non-ascii.h4
-rw-r--r--lib/nonblock.c4
-rw-r--r--lib/nonblock.h4
-rw-r--r--lib/nwlib.c2
-rw-r--r--lib/nwos.c4
-rw-r--r--lib/openldap.c14
-rw-r--r--lib/optiontable.pl118
-rw-r--r--lib/parsedate.c59
-rw-r--r--lib/parsedate.h4
-rw-r--r--lib/pingpong.c61
-rw-r--r--lib/pingpong.h6
-rw-r--r--lib/pop3.c19
-rw-r--r--lib/pop3.h4
-rw-r--r--lib/progress.c17
-rw-r--r--lib/progress.h6
-rw-r--r--lib/psl.c4
-rw-r--r--lib/psl.h4
-rw-r--r--lib/quic.h4
-rw-r--r--lib/rand.c4
-rw-r--r--lib/rand.h4
-rw-r--r--lib/rename.c6
-rw-r--r--lib/rename.h2
-rw-r--r--lib/rtsp.c46
-rw-r--r--lib/rtsp.h4
-rw-r--r--lib/security.c579
-rw-r--r--lib/select.c177
-rw-r--r--lib/select.h17
-rw-r--r--lib/sendf.c179
-rw-r--r--lib/sendf.h6
-rw-r--r--lib/setopt.c294
-rw-r--r--lib/setopt.h2
-rw-r--r--lib/setup-os400.h2
-rw-r--r--lib/setup-vms.h2
-rw-r--r--lib/setup-win32.h5
-rw-r--r--lib/sha256.c2
-rw-r--r--lib/share.c4
-rw-r--r--lib/share.h8
-rw-r--r--lib/sigpipe.h4
-rw-r--r--lib/slist.c4
-rw-r--r--lib/slist.h4
-rw-r--r--lib/smb.c33
-rw-r--r--lib/smb.h11
-rw-r--r--lib/smtp.c27
-rw-r--r--lib/smtp.h2
-rw-r--r--lib/sockaddr.h4
-rw-r--r--lib/socketpair.c6
-rw-r--r--lib/socketpair.h4
-rw-r--r--lib/socks.c169
-rw-r--r--lib/socks.h28
-rw-r--r--lib/socks_gssapi.c6
-rw-r--r--lib/socks_sspi.c2
-rw-r--r--lib/speedcheck.c4
-rw-r--r--lib/speedcheck.h4
-rw-r--r--lib/splay.c10
-rw-r--r--lib/splay.h16
-rw-r--r--lib/strcase.c2
-rw-r--r--lib/strcase.h2
-rw-r--r--lib/strdup.c2
-rw-r--r--lib/strdup.h4
-rw-r--r--lib/strerror.c44
-rw-r--r--lib/strerror.h2
-rw-r--r--lib/strtok.c2
-rw-r--r--lib/strtok.h4
-rw-r--r--lib/strtoofft.c4
-rw-r--r--lib/strtoofft.h4
-rw-r--r--lib/system_win32.c13
-rw-r--r--lib/system_win32.h2
-rw-r--r--lib/telnet.c164
-rw-r--r--lib/telnet.h4
-rw-r--r--lib/tftp.c3
-rw-r--r--lib/tftp.h4
-rw-r--r--lib/timeval.c2
-rw-r--r--lib/timeval.h4
-rw-r--r--lib/transfer.c19
-rw-r--r--lib/transfer.h4
-rw-r--r--lib/url.c223
-rw-r--r--lib/url.h2
-rw-r--r--lib/urlapi-int.h6
-rw-r--r--lib/urlapi.c48
-rw-r--r--lib/urldata.h91
-rw-r--r--lib/vauth/cleartext.c2
-rw-r--r--lib/vauth/cram.c2
-rw-r--r--lib/vauth/digest.c2
-rw-r--r--lib/vauth/digest.h4
-rw-r--r--lib/vauth/digest_sspi.c2
-rw-r--r--lib/vauth/krb5_gssapi.c4
-rw-r--r--lib/vauth/krb5_sspi.c2
-rw-r--r--lib/vauth/ntlm.c3
-rw-r--r--lib/vauth/ntlm.h4
-rw-r--r--lib/vauth/ntlm_sspi.c2
-rw-r--r--lib/vauth/oauth2.c4
-rw-r--r--lib/vauth/spnego_gssapi.c4
-rw-r--r--lib/vauth/spnego_sspi.c2
-rw-r--r--lib/vauth/vauth.c2
-rw-r--r--lib/vauth/vauth.h4
-rw-r--r--lib/version.c24
-rw-r--r--lib/version_win32.c2
-rw-r--r--lib/version_win32.h2
-rw-r--r--lib/vquic/ngtcp2.c96
-rw-r--r--lib/vquic/ngtcp2.h4
-rw-r--r--lib/vquic/quiche.c43
-rw-r--r--lib/vquic/quiche.h5
-rw-r--r--lib/vquic/vquic.c2
-rw-r--r--lib/vquic/vquic.h2
-rw-r--r--lib/vssh/libssh.c69
-rw-r--r--lib/vssh/libssh2.c217
-rw-r--r--lib/vssh/ssh.h8
-rw-r--r--lib/vssh/wolfssh.c10
-rw-r--r--lib/vssh/wolfssh.h2
-rw-r--r--lib/vtls/bearssl.c2
-rw-r--r--lib/vtls/bearssl.h4
-rw-r--r--lib/vtls/gskit.c4
-rw-r--r--lib/vtls/gskit.h4
-rw-r--r--lib/vtls/gtls.c72
-rw-r--r--lib/vtls/gtls.h4
-rw-r--r--lib/vtls/keylog.c2
-rw-r--r--lib/vtls/keylog.h2
-rw-r--r--lib/vtls/mbedtls.c16
-rw-r--r--lib/vtls/mbedtls.h4
-rw-r--r--lib/vtls/mbedtls_threadlock.c2
-rw-r--r--lib/vtls/mbedtls_threadlock.h2
-rw-r--r--lib/vtls/mesalink.c24
-rw-r--r--lib/vtls/mesalink.h6
-rw-r--r--lib/vtls/nss.c67
-rw-r--r--lib/vtls/nssg.h4
-rw-r--r--lib/vtls/openssl.c253
-rw-r--r--lib/vtls/openssl.h4
-rw-r--r--lib/vtls/schannel.c57
-rw-r--r--lib/vtls/schannel.h12
-rw-r--r--lib/vtls/schannel_verify.c2
-rw-r--r--lib/vtls/sectransp.c26
-rw-r--r--lib/vtls/sectransp.h4
-rw-r--r--lib/vtls/vtls.c17
-rw-r--r--lib/vtls/vtls.h18
-rw-r--r--lib/vtls/wolfssl.c24
-rw-r--r--lib/vtls/wolfssl.h4
-rw-r--r--lib/warnless.c4
-rw-r--r--lib/warnless.h2
-rw-r--r--lib/wildcard.c4
-rw-r--r--lib/wildcard.h14
-rw-r--r--lib/x509asn1.c2
-rw-r--r--lib/x509asn1.h2
-rw-r--r--libgnurl.pc.in4
-rw-r--r--m4/curl-compilers.m410
-rw-r--r--m4/curl-confopts.m444
-rw-r--r--m4/curl-functions.m42
-rw-r--r--m4/curl-openssl.m42
-rw-r--r--m4/curl-override.m42
-rw-r--r--m4/curl-reentrant.m42
-rwxr-xr-xmaketgz4
-rw-r--r--packages/Android/Android.mk2
-rw-r--r--packages/DOS/common.dj2
-rw-r--r--packages/Makefile.am20
-rw-r--r--packages/OS400/ccsidcurl.c69
-rw-r--r--packages/OS400/ccsidcurl.h56
-rw-r--r--packages/OS400/chkstrings.c34
-rw-r--r--packages/OS400/curl.inc.in30
-rw-r--r--packages/OS400/initscript.sh2
-rw-r--r--packages/OS400/make-include.sh2
-rw-r--r--packages/OS400/make-lib.sh2
-rw-r--r--packages/OS400/make-src.sh2
-rw-r--r--packages/OS400/make-tests.sh2
-rw-r--r--packages/OS400/makefile.sh2
-rw-r--r--packages/OS400/os400sys.c412
-rw-r--r--packages/OS400/os400sys.h2
-rw-r--r--packages/Symbian/bwins/libcurlu.def60
-rw-r--r--packages/Symbian/eabi/libcurlu.def60
-rw-r--r--packages/Symbian/group/bld.inf10
-rw-r--r--packages/Symbian/group/curl.iby15
-rw-r--r--packages/Symbian/group/curl.mmp64
-rw-r--r--packages/Symbian/group/curl.pkg26
-rw-r--r--packages/Symbian/group/libcurl.iby14
-rw-r--r--packages/Symbian/group/libcurl.mmp67
-rw-r--r--packages/Symbian/group/libcurl.pkg22
-rw-r--r--packages/Symbian/readme.txt93
-rw-r--r--packages/TPF/curl.mak2
-rw-r--r--packages/TPF/maketpf.env_curl2
-rw-r--r--packages/TPF/maketpf.env_curllib2
-rw-r--r--packages/vms/Makefile.am2
-rw-r--r--packages/vms/curl_crtl_init.c2
-rw-r--r--packages/vms/curl_gnv_build_steps.txt2
-rw-r--r--packages/vms/curlmsg.h2
-rw-r--r--packages/vms/curlmsg.msg2
-rw-r--r--packages/vms/curlmsg_vms.h2
-rw-r--r--plan9/include/mkfile4
-rw-r--r--plan9/lib/mkfile4
-rwxr-xr-xplan9/lib/mkfile.inc4
-rw-r--r--plan9/mkfile4
-rw-r--r--plan9/mkfile.proto4
-rw-r--r--plan9/src/mkfile4
-rwxr-xr-xplan9/src/mkfile.inc4
-rw-r--r--scripts/Makefile.am2
-rwxr-xr-xscripts/completion.pl4
-rwxr-xr-xscripts/contributors.sh4
-rwxr-xr-xscripts/contrithanks.sh6
-rwxr-xr-xscripts/copyright.pl15
-rwxr-xr-xscripts/coverage.sh2
-rwxr-xr-xscripts/delta39
-rw-r--r--scripts/installcheck.sh2
-rwxr-xr-xscripts/log2changes.pl2
-rwxr-xr-xscripts/release-notes.pl11
-rwxr-xr-xscripts/singleuse.pl2
-rwxr-xr-xscripts/travis/before_script.sh2
-rwxr-xr-xscripts/travis/iconv-env.sh2
-rwxr-xr-xscripts/travis/script.sh5
-rwxr-xr-xscripts/updatemanpages.pl2
-rw-r--r--src/CMakeLists.txt8
-rw-r--r--src/Makefile.Watcom234
-rw-r--r--src/Makefile.am6
-rw-r--r--src/Makefile.inc8
-rw-r--r--src/Makefile.m3241
-rw-r--r--src/Makefile.netware6
-rw-r--r--src/curl.rc8
-rw-r--r--src/makefile.amiga2
-rw-r--r--src/makefile.dj2
-rwxr-xr-xsrc/mkhelp.pl.in4
-rw-r--r--src/slist_wc.c4
-rw-r--r--src/slist_wc.h4
-rw-r--r--src/tool_binmode.c4
-rw-r--r--src/tool_binmode.h4
-rw-r--r--src/tool_bname.c4
-rw-r--r--src/tool_bname.h4
-rw-r--r--src/tool_cb_dbg.c4
-rw-r--r--src/tool_cb_dbg.h4
-rw-r--r--src/tool_cb_hdr.c70
-rw-r--r--src/tool_cb_hdr.h4
-rw-r--r--src/tool_cb_prg.c2
-rw-r--r--src/tool_cb_prg.h4
-rw-r--r--src/tool_cb_rea.c2
-rw-r--r--src/tool_cb_rea.h4
-rw-r--r--src/tool_cb_see.c2
-rw-r--r--src/tool_cb_see.h2
-rw-r--r--src/tool_cb_wrt.c34
-rw-r--r--src/tool_cb_wrt.h2
-rw-r--r--src/tool_cfgable.c5
-rw-r--r--src/tool_cfgable.h6
-rw-r--r--src/tool_convert.c4
-rw-r--r--src/tool_convert.h4
-rw-r--r--src/tool_dirhie.c2
-rw-r--r--src/tool_dirhie.h4
-rw-r--r--src/tool_doswin.c2
-rw-r--r--src/tool_doswin.h2
-rw-r--r--src/tool_easysrc.c8
-rw-r--r--src/tool_easysrc.h4
-rw-r--r--src/tool_filetime.c7
-rw-r--r--src/tool_filetime.h4
-rw-r--r--src/tool_formparse.c2
-rw-r--r--src/tool_formparse.h2
-rw-r--r--src/tool_getparam.c28
-rw-r--r--src/tool_getparam.h4
-rw-r--r--src/tool_getpass.c12
-rw-r--r--src/tool_getpass.h4
-rw-r--r--src/tool_help.c848
-rw-r--r--src/tool_help.h6
-rw-r--r--src/tool_helpers.c4
-rw-r--r--src/tool_helpers.h4
-rw-r--r--src/tool_homedir.c48
-rw-r--r--src/tool_homedir.h6
-rw-r--r--src/tool_hugehelp.c.cvs2
-rw-r--r--src/tool_hugehelp.h4
-rw-r--r--src/tool_libinfo.c4
-rw-r--r--src/tool_libinfo.h4
-rw-r--r--src/tool_main.c7
-rw-r--r--src/tool_main.h4
-rw-r--r--src/tool_metalink.c2
-rw-r--r--src/tool_metalink.h2
-rw-r--r--src/tool_msgs.c4
-rw-r--r--src/tool_msgs.h4
-rw-r--r--src/tool_operate.c140
-rw-r--r--src/tool_operate.h7
-rw-r--r--src/tool_operhlp.c2
-rw-r--r--src/tool_operhlp.h4
-rw-r--r--src/tool_panykey.c12
-rw-r--r--src/tool_panykey.h10
-rw-r--r--src/tool_paramhlp.c118
-rw-r--r--src/tool_paramhlp.h4
-rw-r--r--src/tool_parsecfg.c73
-rw-r--r--src/tool_parsecfg.h4
-rw-r--r--src/tool_progress.c6
-rw-r--r--src/tool_progress.h4
-rw-r--r--src/tool_sdecls.h2
-rw-r--r--src/tool_setopt.c63
-rw-r--r--src/tool_setopt.h15
-rw-r--r--src/tool_setup.h4
-rw-r--r--src/tool_sleep.c2
-rw-r--r--src/tool_sleep.h4
-rw-r--r--src/tool_strdup.c2
-rw-r--r--src/tool_strdup.h4
-rw-r--r--src/tool_urlglob.c52
-rw-r--r--src/tool_urlglob.h2
-rw-r--r--src/tool_util.c2
-rw-r--r--src/tool_util.h4
-rw-r--r--src/tool_version.h4
-rw-r--r--src/tool_vms.c2
-rw-r--r--src/tool_vms.h4
-rw-r--r--src/tool_writeout.c95
-rw-r--r--src/tool_writeout.h6
-rw-r--r--src/tool_writeout_json.c24
-rw-r--r--src/tool_writeout_json.h6
-rw-r--r--src/tool_xattr.c4
-rw-r--r--src/tool_xattr.h4
-rw-r--r--tests/CMakeLists.txt7
-rw-r--r--tests/FILEFORMAT.md42
-rw-r--r--tests/Makefile.am21
-rw-r--r--tests/README.md (renamed from tests/README)214
-rw-r--r--tests/appveyor.pm12
-rw-r--r--tests/azure.pm21
-rwxr-xr-xtests/badsymbols.pl.in2
-rw-r--r--tests/certs/Makefile.am2
-rw-r--r--tests/certs/scripts/Makefile.am2
-rwxr-xr-xtests/convsrctest.pl.in2
-rw-r--r--tests/data/CMakeLists.txt2
-rw-r--r--tests/data/DISABLED30
-rw-r--r--tests/data/Makefile.am2
-rw-r--r--tests/data/Makefile.inc91
-rw-r--r--tests/data/test14
-rw-r--r--tests/data/test104
-rw-r--r--tests/data/test10016
-rw-r--r--tests/data/test100210
-rw-r--r--tests/data/test10044
-rw-r--r--tests/data/test10087
-rw-r--r--tests/data/test10116
-rw-r--r--tests/data/test10126
-rw-r--r--tests/data/test10155
-rw-r--r--tests/data/test10218
-rw-r--r--tests/data/test10246
-rw-r--r--tests/data/test10256
-rw-r--r--tests/data/test10284
-rw-r--r--tests/data/test10294
-rw-r--r--tests/data/test10306
-rw-r--r--tests/data/test10315
-rw-r--r--tests/data/test10324
-rw-r--r--tests/data/test10334
-rw-r--r--tests/data/test10353
-rw-r--r--tests/data/test10404
-rw-r--r--tests/data/test10414
-rw-r--r--tests/data/test10424
-rw-r--r--tests/data/test10434
-rw-r--r--tests/data/test10454
-rw-r--r--tests/data/test10464
-rw-r--r--tests/data/test10515
-rw-r--r--tests/data/test10525
-rw-r--r--tests/data/test10536
-rw-r--r--tests/data/test10545
-rw-r--r--tests/data/test10554
-rw-r--r--tests/data/test10565
-rw-r--r--tests/data/test10584
-rw-r--r--tests/data/test10594
-rw-r--r--tests/data/test106010
-rw-r--r--tests/data/test106110
-rw-r--r--tests/data/test10645
-rw-r--r--tests/data/test10655
-rw-r--r--tests/data/test10665
-rw-r--r--tests/data/test10675
-rw-r--r--tests/data/test10684
-rw-r--r--tests/data/test10704
-rw-r--r--tests/data/test10715
-rw-r--r--tests/data/test10724
-rw-r--r--tests/data/test10734
-rw-r--r--tests/data/test10745
-rw-r--r--tests/data/test10755
-rw-r--r--tests/data/test10766
-rw-r--r--tests/data/test10775
-rw-r--r--tests/data/test10786
-rw-r--r--tests/data/test10795
-rw-r--r--tests/data/test10805
-rw-r--r--tests/data/test10815
-rw-r--r--tests/data/test10824
-rw-r--r--tests/data/test10834
-rw-r--r--tests/data/test10876
-rw-r--r--tests/data/test10886
-rw-r--r--tests/data/test10895
-rw-r--r--tests/data/test10905
-rw-r--r--tests/data/test10924
-rw-r--r--tests/data/test10956
-rw-r--r--tests/data/test10961
-rw-r--r--tests/data/test10977
-rw-r--r--tests/data/test10985
-rw-r--r--tests/data/test115
-rw-r--r--tests/data/test110010
-rw-r--r--tests/data/test11014
-rw-r--r--tests/data/test11045
-rw-r--r--tests/data/test11056
-rw-r--r--tests/data/test11064
-rw-r--r--tests/data/test11094
-rw-r--r--tests/data/test11104
-rw-r--r--tests/data/test11114
-rw-r--r--tests/data/test11154
-rw-r--r--tests/data/test11164
-rw-r--r--tests/data/test11175
-rw-r--r--tests/data/test11184
-rw-r--r--tests/data/test11191
-rw-r--r--tests/data/test11214
-rw-r--r--tests/data/test11224
-rw-r--r--tests/data/test11234
-rw-r--r--tests/data/test11244
-rw-r--r--tests/data/test11254
-rw-r--r--tests/data/test11264
-rw-r--r--tests/data/test11274
-rw-r--r--tests/data/test11285
-rw-r--r--tests/data/test11297
-rw-r--r--tests/data/test11305
-rw-r--r--tests/data/test11315
-rw-r--r--tests/data/test11334
-rw-r--r--tests/data/test11345
-rw-r--r--tests/data/test11362
-rw-r--r--tests/data/test11386
-rw-r--r--tests/data/test11415
-rw-r--r--tests/data/test11424
-rw-r--r--tests/data/test11434
-rw-r--r--tests/data/test11444
-rw-r--r--tests/data/test11484
-rw-r--r--tests/data/test11505
-rw-r--r--tests/data/test11516
-rw-r--r--tests/data/test11546
-rw-r--r--tests/data/test11556
-rw-r--r--tests/data/test11574
-rw-r--r--tests/data/test11584
-rw-r--r--tests/data/test11594
-rw-r--r--tests/data/test11606
-rw-r--r--tests/data/test11616
-rw-r--r--tests/data/test11644
-rw-r--r--tests/data/test11665
-rw-r--r--tests/data/test11685
-rw-r--r--tests/data/test11704
-rw-r--r--tests/data/test11714
-rw-r--r--tests/data/test11724
-rw-r--r--tests/data/test11744
-rw-r--r--tests/data/test11764
-rw-r--r--tests/data/test11784
-rw-r--r--tests/data/test1181
-rw-r--r--tests/data/test1191
-rw-r--r--tests/data/test11975
-rw-r--r--tests/data/test124
-rw-r--r--tests/data/test12045
-rw-r--r--tests/data/test12054
-rw-r--r--tests/data/test12104
-rw-r--r--tests/data/test12124
-rw-r--r--tests/data/test12134
-rw-r--r--tests/data/test12144
-rw-r--r--tests/data/test12157
-rw-r--r--tests/data/test12165
-rw-r--r--tests/data/test12186
-rw-r--r--tests/data/test122153
-rw-r--r--tests/data/test122253
-rw-r--r--tests/data/test12234
-rw-r--r--tests/data/test12285
-rw-r--r--tests/data/test12295
-rw-r--r--tests/data/test12305
-rw-r--r--tests/data/test12315
-rw-r--r--tests/data/test12325
-rw-r--r--tests/data/test123511
-rw-r--r--tests/data/test12374
-rw-r--r--tests/data/test12394
-rw-r--r--tests/data/test12405
-rw-r--r--tests/data/test12415
-rw-r--r--tests/data/test12444
-rw-r--r--tests/data/test12454
-rw-r--r--tests/data/test12465
-rw-r--r--tests/data/test12484
-rw-r--r--tests/data/test12494
-rw-r--r--tests/data/test12504
-rw-r--r--tests/data/test12514
-rw-r--r--tests/data/test12524
-rw-r--r--tests/data/test12534
-rw-r--r--tests/data/test12544
-rw-r--r--tests/data/test12554
-rw-r--r--tests/data/test12564
-rw-r--r--tests/data/test12574
-rw-r--r--tests/data/test12585
-rw-r--r--tests/data/test12594
-rw-r--r--tests/data/test12614
-rw-r--r--tests/data/test12654
-rw-r--r--tests/data/test12664
-rw-r--r--tests/data/test12674
-rw-r--r--tests/data/test12704
-rw-r--r--tests/data/test12714
-rw-r--r--tests/data/test12807
-rw-r--r--tests/data/test12834
-rw-r--r--tests/data/test12845
-rw-r--r--tests/data/test12855
-rw-r--r--tests/data/test12867
-rw-r--r--tests/data/test12875
-rw-r--r--tests/data/test12885
-rw-r--r--tests/data/test12904
-rw-r--r--tests/data/test12924
-rw-r--r--tests/data/test12934
-rw-r--r--tests/data/test12944
-rw-r--r--tests/data/test12954
-rw-r--r--tests/data/test12964
-rw-r--r--tests/data/test129765
-rw-r--r--tests/data/test12984
-rw-r--r--tests/data/test12994
-rw-r--r--tests/data/test134
-rw-r--r--tests/data/test13107
-rw-r--r--tests/data/test13114
-rw-r--r--tests/data/test13124
-rw-r--r--tests/data/test13134
-rw-r--r--tests/data/test13145
-rw-r--r--tests/data/test13154
-rw-r--r--tests/data/test13174
-rw-r--r--tests/data/test13185
-rw-r--r--tests/data/test13195
-rw-r--r--tests/data/test13205
-rw-r--r--tests/data/test13215
-rw-r--r--tests/data/test13224
-rw-r--r--tests/data/test13244
-rw-r--r--tests/data/test13255
-rw-r--r--tests/data/test13285
-rw-r--r--tests/data/test13315
-rw-r--r--tests/data/test13326
-rw-r--r--tests/data/test13334
-rw-r--r--tests/data/test13344
-rw-r--r--tests/data/test13354
-rw-r--r--tests/data/test13364
-rw-r--r--tests/data/test13374
-rw-r--r--tests/data/test13384
-rw-r--r--tests/data/test13394
-rw-r--r--tests/data/test13404
-rw-r--r--tests/data/test13414
-rw-r--r--tests/data/test13424
-rw-r--r--tests/data/test13434
-rw-r--r--tests/data/test13444
-rw-r--r--tests/data/test13454
-rw-r--r--tests/data/test13464
-rw-r--r--tests/data/test13474
-rw-r--r--tests/data/test13644
-rw-r--r--tests/data/test13654
-rw-r--r--tests/data/test13664
-rw-r--r--tests/data/test13674
-rw-r--r--tests/data/test13684
-rw-r--r--tests/data/test13694
-rw-r--r--tests/data/test13704
-rw-r--r--tests/data/test13714
-rw-r--r--tests/data/test13724
-rw-r--r--tests/data/test13734
-rw-r--r--tests/data/test13744
-rw-r--r--tests/data/test13754
-rw-r--r--tests/data/test13764
-rw-r--r--tests/data/test13774
-rw-r--r--tests/data/test1381
-rw-r--r--tests/data/test145
-rw-r--r--tests/data/test14008
-rw-r--r--tests/data/test14018
-rw-r--r--tests/data/test14028
-rw-r--r--tests/data/test14038
-rw-r--r--tests/data/test14047
-rw-r--r--tests/data/test14053
-rw-r--r--tests/data/test14063
-rw-r--r--tests/data/test14073
-rw-r--r--tests/data/test14085
-rw-r--r--tests/data/test14114
-rw-r--r--tests/data/test141210
-rw-r--r--tests/data/test14135
-rw-r--r--tests/data/test14156
-rw-r--r--tests/data/test14164
-rw-r--r--tests/data/test14174
-rw-r--r--tests/data/test14187
-rw-r--r--tests/data/test14195
-rw-r--r--tests/data/test14203
-rw-r--r--tests/data/test14215
-rw-r--r--tests/data/test14224
-rw-r--r--tests/data/test14234
-rw-r--r--tests/data/test14244
-rw-r--r--tests/data/test1425bin1726 -> 1721 bytes
-rw-r--r--tests/data/test1426bin1663 -> 1658 bytes
-rw-r--r--tests/data/test14287
-rw-r--r--tests/data/test14294
-rw-r--r--tests/data/test14304
-rw-r--r--tests/data/test14314
-rw-r--r--tests/data/test14324
-rw-r--r--tests/data/test14334
-rw-r--r--tests/data/test14344
-rw-r--r--tests/data/test14354
-rw-r--r--tests/data/test14366
-rw-r--r--tests/data/test14376
-rw-r--r--tests/data/test14384
-rw-r--r--tests/data/test14396
-rw-r--r--tests/data/test14434
-rw-r--r--tests/data/test14485
-rw-r--r--tests/data/test14554
-rw-r--r--tests/data/test14565
-rw-r--r--tests/data/test14574
-rw-r--r--tests/data/test14584
-rw-r--r--tests/data/test14603
-rw-r--r--tests/data/test146153
-rw-r--r--tests/data/test146261
-rw-r--r--tests/data/test146344
-rw-r--r--tests/data/test146444
-rw-r--r--tests/data/test1465bin0 -> 2964 bytes
-rw-r--r--tests/data/test154
-rw-r--r--tests/data/test1507
-rw-r--r--tests/data/test15023
-rw-r--r--tests/data/test15033
-rw-r--r--tests/data/test15043
-rw-r--r--tests/data/test15053
-rw-r--r--tests/data/test1515
-rw-r--r--tests/data/test1525
-rw-r--r--tests/data/test15246
-rw-r--r--tests/data/test15310
-rw-r--r--tests/data/test15383
-rw-r--r--tests/data/test1546
-rw-r--r--tests/data/test1557
-rw-r--r--tests/data/test15513
-rw-r--r--tests/data/test15565
-rw-r--r--tests/data/test1565
-rw-r--r--tests/data/test15619
-rw-r--r--tests/data/test15626
-rw-r--r--tests/data/test15634
-rw-r--r--tests/data/test15666
-rw-r--r--tests/data/test15673
-rw-r--r--tests/data/test1574
-rw-r--r--tests/data/test1583
-rw-r--r--tests/data/test1595
-rw-r--r--tests/data/test15913
-rw-r--r--tests/data/test15933
-rw-r--r--tests/data/test15943
-rw-r--r--tests/data/test15953
-rw-r--r--tests/data/test15963
-rw-r--r--tests/data/test164
-rw-r--r--tests/data/test1605
-rw-r--r--tests/data/test1625
-rw-r--r--tests/data/test1634
-rw-r--r--tests/data/test16304
-rw-r--r--tests/data/test16313
-rw-r--r--tests/data/test16323
-rw-r--r--tests/data/test16337
-rw-r--r--tests/data/test1644
-rw-r--r--tests/data/test1655
-rw-r--r--tests/data/test16532
-rw-r--r--tests/data/test16542
-rw-r--r--tests/data/test1664
-rw-r--r--tests/data/test166081
-rw-r--r--tests/data/test1677
-rw-r--r--tests/data/test1689
-rw-r--r--tests/data/test1699
-rw-r--r--tests/data/test1705
-rw-r--r--tests/data/test17007
-rw-r--r--tests/data/test17015
-rw-r--r--tests/data/test17025
-rw-r--r--tests/data/test1716
-rw-r--r--tests/data/test1726
-rw-r--r--tests/data/test1734
-rw-r--r--tests/data/test1745
-rw-r--r--tests/data/test1757
-rw-r--r--tests/data/test1767
-rw-r--r--tests/data/test1775
-rw-r--r--tests/data/test1784
-rw-r--r--tests/data/test1794
-rw-r--r--tests/data/test189
-rw-r--r--tests/data/test1804
-rw-r--r--tests/data/test18004
-rw-r--r--tests/data/test18014
-rw-r--r--tests/data/test1814
-rw-r--r--tests/data/test1837
-rw-r--r--tests/data/test1846
-rw-r--r--tests/data/test1856
-rw-r--r--tests/data/test1864
-rw-r--r--tests/data/test1875
-rw-r--r--tests/data/test1887
-rw-r--r--tests/data/test1897
-rw-r--r--tests/data/test190061
-rw-r--r--tests/data/test190163
-rw-r--r--tests/data/test190262
-rw-r--r--tests/data/test190362
-rw-r--r--tests/data/test19047
-rw-r--r--tests/data/test19055
-rw-r--r--tests/data/test19063
-rw-r--r--tests/data/test19073
-rw-r--r--tests/data/test190820
-rw-r--r--tests/data/test19095
-rw-r--r--tests/data/test19105
-rw-r--r--tests/data/test1911 (renamed from tests/data/test1541)19
-rw-r--r--tests/data/test191230
-rw-r--r--tests/data/test191341
-rw-r--r--tests/data/test191442
-rw-r--r--tests/data/test191550
-rw-r--r--tests/data/test1924
-rw-r--r--tests/data/test1935
-rw-r--r--tests/data/test1944
-rw-r--r--tests/data/test1975
-rw-r--r--tests/data/test1985
-rw-r--r--tests/data/test1995
-rw-r--r--tests/data/test24
-rw-r--r--tests/data/test20014
-rw-r--r--tests/data/test20024
-rw-r--r--tests/data/test20035
-rw-r--r--tests/data/test20054
-rw-r--r--tests/data/test20064
-rw-r--r--tests/data/test20074
-rw-r--r--tests/data/test20084
-rw-r--r--tests/data/test20094
-rw-r--r--tests/data/test20104
-rw-r--r--tests/data/test20114
-rw-r--r--tests/data/test20124
-rw-r--r--tests/data/test20233
-rw-r--r--tests/data/test20243
-rw-r--r--tests/data/test20253
-rw-r--r--tests/data/test20263
-rw-r--r--tests/data/test20273
-rw-r--r--tests/data/test20283
-rw-r--r--tests/data/test20293
-rw-r--r--tests/data/test20303
-rw-r--r--tests/data/test20313
-rw-r--r--tests/data/test20323
-rw-r--r--tests/data/test2033125
-rw-r--r--tests/data/test20344
-rw-r--r--tests/data/test20363
-rw-r--r--tests/data/test20373
-rw-r--r--tests/data/test20405
-rw-r--r--tests/data/test20414
-rw-r--r--tests/data/test20465
-rw-r--r--tests/data/test20475
-rw-r--r--tests/data/test20497
-rw-r--r--tests/data/test20505
-rw-r--r--tests/data/test20516
-rw-r--r--tests/data/test20525
-rw-r--r--tests/data/test20535
-rw-r--r--tests/data/test20547
-rw-r--r--tests/data/test20555
-rw-r--r--tests/data/test20564
-rw-r--r--tests/data/test20575
-rw-r--r--tests/data/test20586
-rw-r--r--tests/data/test20596
-rw-r--r--tests/data/test2067
-rw-r--r--tests/data/test20606
-rw-r--r--tests/data/test20616
-rw-r--r--tests/data/test20626
-rw-r--r--tests/data/test20636
-rw-r--r--tests/data/test20646
-rw-r--r--tests/data/test20656
-rw-r--r--tests/data/test20666
-rw-r--r--tests/data/test20675
-rw-r--r--tests/data/test20685
-rw-r--r--tests/data/test20695
-rw-r--r--tests/data/test2074
-rw-r--r--tests/data/test20704
-rw-r--r--tests/data/test20734
-rw-r--r--tests/data/test20744
-rw-r--r--tests/data/test20765
-rw-r--r--tests/data/test20784
-rw-r--r--tests/data/test2084
-rw-r--r--tests/data/test2097
-rw-r--r--tests/data/test2100bin1647 -> 1642 bytes
-rw-r--r--tests/data/test2137
-rw-r--r--tests/data/test2144
-rw-r--r--tests/data/test2174
-rw-r--r--tests/data/test2184
-rw-r--r--tests/data/test225
-rw-r--r--tests/data/test2204
-rw-r--r--tests/data/test2214
-rw-r--r--tests/data/test2224
-rw-r--r--tests/data/test2234
-rw-r--r--tests/data/test2244
-rw-r--r--tests/data/test2304
-rw-r--r--tests/data/test2324
-rw-r--r--tests/data/test2335
-rw-r--r--tests/data/test2345
-rw-r--r--tests/data/test2353
-rw-r--r--tests/data/test2361
-rw-r--r--tests/data/test2397
-rw-r--r--tests/data/test245
-rw-r--r--tests/data/test2404
-rw-r--r--tests/data/test2414
-rw-r--r--tests/data/test2424
-rw-r--r--tests/data/test2439
-rw-r--r--tests/data/test2457
-rw-r--r--tests/data/test2467
-rw-r--r--tests/data/test2494
-rw-r--r--tests/data/test2515
-rw-r--r--tests/data/test2564
-rw-r--r--tests/data/test2579
-rw-r--r--tests/data/test2586
-rw-r--r--tests/data/test2596
-rw-r--r--tests/data/test265
-rw-r--r--tests/data/test2604
-rw-r--r--tests/data/test262bin1137 -> 1132 bytes
-rw-r--r--tests/data/test2634
-rw-r--r--tests/data/test2644
-rw-r--r--tests/data/test2657
-rw-r--r--tests/data/test2664
-rw-r--r--tests/data/test2677
-rw-r--r--tests/data/test2684
-rw-r--r--tests/data/test2694
-rw-r--r--tests/data/test276
-rw-r--r--tests/data/test2736
-rw-r--r--tests/data/test2745
-rw-r--r--tests/data/test2757
-rw-r--r--tests/data/test2765
-rw-r--r--tests/data/test2775
-rw-r--r--tests/data/test2784
-rw-r--r--tests/data/test2794
-rw-r--r--tests/data/test285
-rw-r--r--tests/data/test2814
-rw-r--r--tests/data/test2824
-rw-r--r--tests/data/test294
-rw-r--r--tests/data/test2924
-rw-r--r--tests/data/test2934
-rw-r--r--tests/data/test2994
-rw-r--r--tests/data/test34
-rw-r--r--tests/data/test304
-rw-r--r--tests/data/test3004
-rw-r--r--tests/data/test30004
-rw-r--r--tests/data/test30014
-rw-r--r--tests/data/test300857
-rw-r--r--tests/data/test300957
-rw-r--r--tests/data/test3014
-rw-r--r--tests/data/test301157
-rw-r--r--tests/data/test301260
-rw-r--r--tests/data/test301368
-rw-r--r--tests/data/test301456
-rw-r--r--tests/data/test301578
-rw-r--r--tests/data/test3023
-rw-r--r--tests/data/test3034
-rw-r--r--tests/data/test3044
-rw-r--r--tests/data/test3053
-rw-r--r--tests/data/test3064
-rw-r--r--tests/data/test3074
-rw-r--r--tests/data/test3095
-rw-r--r--tests/data/test316
-rw-r--r--tests/data/test3104
-rw-r--r--tests/data/test3144
-rw-r--r--tests/data/test3154
-rw-r--r--tests/data/test3164
-rw-r--r--tests/data/test3175
-rw-r--r--tests/data/test3185
-rw-r--r--tests/data/test3194
-rw-r--r--tests/data/test325
-rw-r--r--tests/data/test3254
-rw-r--r--tests/data/test3264
-rw-r--r--tests/data/test3277
-rw-r--r--tests/data/test3282
-rw-r--r--tests/data/test3295
-rw-r--r--tests/data/test335
-rw-r--r--tests/data/test3305
-rw-r--r--tests/data/test3315
-rw-r--r--tests/data/test3344
-rw-r--r--tests/data/test3359
-rw-r--r--tests/data/test3385
-rw-r--r--tests/data/test3398
-rw-r--r--tests/data/test344
-rw-r--r--tests/data/test3413
-rw-r--r--tests/data/test3426
-rw-r--r--tests/data/test3438
-rw-r--r--tests/data/test3446
-rw-r--r--tests/data/test3458
-rw-r--r--tests/data/test3464
-rw-r--r--tests/data/test34760
-rw-r--r--tests/data/test34861
-rw-r--r--tests/data/test35bin810 -> 805 bytes
-rw-r--r--tests/data/test3554
-rw-r--r--tests/data/test3566
-rw-r--r--tests/data/test3575
-rw-r--r--tests/data/test3585
-rw-r--r--tests/data/test3595
-rw-r--r--tests/data/test364
-rw-r--r--tests/data/test374
-rw-r--r--tests/data/test384
-rw-r--r--tests/data/test394
-rw-r--r--tests/data/test3934
-rw-r--r--tests/data/test3944
-rw-r--r--tests/data/test3954
-rw-r--r--tests/data/test3964
-rw-r--r--tests/data/test3974
-rw-r--r--tests/data/test45
-rw-r--r--tests/data/test406
-rw-r--r--tests/data/test426
-rw-r--r--tests/data/test435
-rw-r--r--tests/data/test4306
-rw-r--r--tests/data/test4316
-rw-r--r--tests/data/test4326
-rw-r--r--tests/data/test43357
-rw-r--r--tests/data/test43446
-rw-r--r--tests/data/test444
-rw-r--r--tests/data/test455
-rw-r--r--tests/data/test468
-rw-r--r--tests/data/test474
-rw-r--r--tests/data/test485
-rw-r--r--tests/data/test496
-rw-r--r--tests/data/test4905
-rw-r--r--tests/data/test4914
-rw-r--r--tests/data/test4927
-rw-r--r--tests/data/test49361
-rw-r--r--tests/data/test54
-rw-r--r--tests/data/test506
-rw-r--r--tests/data/test5067
-rw-r--r--tests/data/test516
-rw-r--r--tests/data/test5114
-rw-r--r--tests/data/test5123
-rw-r--r--tests/data/test5143
-rw-r--r--tests/data/test5153
-rw-r--r--tests/data/test5163
-rw-r--r--tests/data/test526
-rw-r--r--tests/data/test5223
-rw-r--r--tests/data/test5233
-rw-r--r--tests/data/test534
-rw-r--r--tests/data/test53083
-rw-r--r--tests/data/test5332
-rw-r--r--tests/data/test5342
-rw-r--r--tests/data/test544
-rw-r--r--tests/data/test5403
-rw-r--r--tests/data/test5443
-rw-r--r--tests/data/test5462
-rw-r--r--tests/data/test5476
-rw-r--r--tests/data/test5486
-rw-r--r--tests/data/test5493
-rw-r--r--tests/data/test556
-rw-r--r--tests/data/test5503
-rw-r--r--tests/data/test5513
-rw-r--r--tests/data/test552bin142947 -> 2967 bytes
-rw-r--r--tests/data/test55321
-rw-r--r--tests/data/test5556
-rw-r--r--tests/data/test5563
-rw-r--r--tests/data/test5584
-rw-r--r--tests/data/test564
-rw-r--r--tests/data/test5603
-rw-r--r--tests/data/test5613
-rw-r--r--tests/data/test574
-rw-r--r--tests/data/test5733
-rw-r--r--tests/data/test584
-rw-r--r--tests/data/test5803
-rw-r--r--tests/data/test5813
-rw-r--r--tests/data/test584102
-rw-r--r--tests/data/test5853
-rw-r--r--tests/data/test5893
-rw-r--r--tests/data/test594
-rw-r--r--tests/data/test5907
-rw-r--r--tests/data/test64
-rw-r--r--tests/data/test604
-rw-r--r--tests/data/test616
-rw-r--r--tests/data/test627
-rw-r--r--tests/data/test634
-rw-r--r--tests/data/test646
-rw-r--r--tests/data/test656
-rw-r--r--tests/data/test6583
-rw-r--r--tests/data/test6593
-rw-r--r--tests/data/test664
-rw-r--r--tests/data/test6625
-rw-r--r--tests/data/test6635
-rw-r--r--tests/data/test6696
-rw-r--r--tests/data/test677
-rw-r--r--tests/data/test6743
-rw-r--r--tests/data/test687
-rw-r--r--tests/data/test699
-rw-r--r--tests/data/test74
-rw-r--r--tests/data/test707
-rw-r--r--tests/data/test7004
-rw-r--r--tests/data/test7014
-rw-r--r--tests/data/test7022
-rw-r--r--tests/data/test7032
-rw-r--r--tests/data/test7084
-rw-r--r--tests/data/test7094
-rw-r--r--tests/data/test7104
-rw-r--r--tests/data/test7162
-rw-r--r--tests/data/test7174
-rw-r--r--tests/data/test727
-rw-r--r--tests/data/test736
-rw-r--r--tests/data/test745
-rw-r--r--tests/data/test753
-rw-r--r--tests/data/test763
-rw-r--r--tests/data/test774
-rw-r--r--tests/data/test784
-rw-r--r--tests/data/test794
-rw-r--r--tests/data/test84
-rw-r--r--tests/data/test807
-rw-r--r--tests/data/test817
-rw-r--r--tests/data/test825
-rw-r--r--tests/data/test837
-rw-r--r--tests/data/test845
-rw-r--r--tests/data/test855
-rw-r--r--tests/data/test869
-rw-r--r--tests/data/test886
-rw-r--r--tests/data/test8911
-rw-r--r--tests/data/test94
-rw-r--r--tests/data/test9013
-rw-r--r--tests/data/test919
-rw-r--r--tests/data/test924
-rw-r--r--tests/data/test934
-rw-r--r--tests/data/test945
-rw-r--r--tests/data/test957
-rw-r--r--tests/data/test974
-rw-r--r--tests/data/test9706
-rw-r--r--tests/data/test9715
-rw-r--r--tests/data/test984
-rw-r--r--tests/data/test994
-rwxr-xr-xtests/dictserver.py.in11
-rw-r--r--tests/directories.pm2
-rwxr-xr-xtests/disable-scan.pl.in4
-rw-r--r--tests/error-codes.pl.in4
-rwxr-xr-xtests/extern-scan.pl.in2
-rw-r--r--tests/ftp.pm2
-rwxr-xr-xtests/ftpserver.pl.in19
-rwxr-xr-xtests/fuzz/download_fuzzer.sh2
-rw-r--r--tests/getpart.pm9
-rwxr-xr-xtests/http2-server.pl.in2
-rwxr-xr-xtests/httpserver.pl.in2
-rwxr-xr-xtests/keywords.pl.in2
-rw-r--r--tests/libtest/.gitignore2
-rw-r--r--tests/libtest/CMakeLists.txt2
-rw-r--r--tests/libtest/Makefile.am2
-rw-r--r--tests/libtest/Makefile.inc43
-rw-r--r--tests/libtest/chkdecimalpoint.c4
-rw-r--r--tests/libtest/chkhostname.c4
-rw-r--r--tests/libtest/first.c4
-rw-r--r--tests/libtest/lib1156.c2
-rw-r--r--tests/libtest/lib1500.c4
-rw-r--r--tests/libtest/lib1501.c4
-rw-r--r--tests/libtest/lib1502.c4
-rw-r--r--tests/libtest/lib1506.c4
-rw-r--r--tests/libtest/lib1507.c2
-rw-r--r--tests/libtest/lib1508.c2
-rw-r--r--tests/libtest/lib1509.c2
-rw-r--r--tests/libtest/lib1510.c4
-rw-r--r--tests/libtest/lib1511.c4
-rw-r--r--tests/libtest/lib1512.c4
-rw-r--r--tests/libtest/lib1513.c4
-rw-r--r--tests/libtest/lib1514.c2
-rw-r--r--tests/libtest/lib1515.c2
-rw-r--r--tests/libtest/lib1517.c4
-rw-r--r--tests/libtest/lib1518.c4
-rw-r--r--tests/libtest/lib1520.c2
-rw-r--r--tests/libtest/lib1522.c4
-rw-r--r--tests/libtest/lib1523.c9
-rw-r--r--tests/libtest/lib1525.c2
-rw-r--r--tests/libtest/lib1526.c2
-rw-r--r--tests/libtest/lib1527.c2
-rw-r--r--tests/libtest/lib1528.c4
-rw-r--r--tests/libtest/lib1529.c4
-rw-r--r--tests/libtest/lib1530.c4
-rw-r--r--tests/libtest/lib1531.c2
-rw-r--r--tests/libtest/lib1532.c4
-rw-r--r--tests/libtest/lib1533.c2
-rw-r--r--tests/libtest/lib1534.c4
-rw-r--r--tests/libtest/lib1535.c2
-rw-r--r--tests/libtest/lib1536.c2
-rw-r--r--tests/libtest/lib1537.c4
-rw-r--r--tests/libtest/lib1538.c16
-rw-r--r--tests/libtest/lib1540.c2
-rw-r--r--tests/libtest/lib1541.c11
-rw-r--r--tests/libtest/lib1550.c6
-rw-r--r--tests/libtest/lib1551.c4
-rw-r--r--tests/libtest/lib1552.c4
-rw-r--r--tests/libtest/lib1553.c4
-rw-r--r--tests/libtest/lib1554.c2
-rw-r--r--tests/libtest/lib1555.c4
-rw-r--r--tests/libtest/lib1556.c4
-rw-r--r--tests/libtest/lib1557.c4
-rw-r--r--tests/libtest/lib1558.c6
-rw-r--r--tests/libtest/lib1559.c4
-rw-r--r--tests/libtest/lib1560.c19
-rw-r--r--tests/libtest/lib1564.c2
-rw-r--r--tests/libtest/lib1565.c4
-rw-r--r--tests/libtest/lib1567.c2
-rw-r--r--tests/libtest/lib1591.c4
-rw-r--r--tests/libtest/lib1592.c12
-rw-r--r--tests/libtest/lib1593.c4
-rw-r--r--tests/libtest/lib1594.c4
-rw-r--r--tests/libtest/lib1900.c2
-rw-r--r--tests/libtest/lib1905.c4
-rw-r--r--tests/libtest/lib1906.c4
-rw-r--r--tests/libtest/lib1907.c4
-rw-r--r--tests/libtest/lib1908.c17
-rw-r--r--tests/libtest/lib1910.c2
-rw-r--r--tests/libtest/lib1911.c89
-rw-r--r--tests/libtest/lib1912.c80
-rw-r--r--tests/libtest/lib1913.c48
-rw-r--r--tests/libtest/lib1915.c95
-rw-r--r--tests/libtest/lib3010.c2
-rw-r--r--tests/libtest/lib500.c2
-rw-r--r--tests/libtest/lib501.c2
-rw-r--r--tests/libtest/lib502.c2
-rw-r--r--tests/libtest/lib503.c2
-rw-r--r--tests/libtest/lib504.c2
-rw-r--r--tests/libtest/lib505.c6
-rw-r--r--tests/libtest/lib506.c4
-rw-r--r--tests/libtest/lib507.c4
-rw-r--r--tests/libtest/lib508.c4
-rw-r--r--tests/libtest/lib509.c2
-rw-r--r--tests/libtest/lib510.c4
-rw-r--r--tests/libtest/lib511.c4
-rw-r--r--tests/libtest/lib512.c2
-rw-r--r--tests/libtest/lib513.c4
-rw-r--r--tests/libtest/lib514.c4
-rw-r--r--tests/libtest/lib515.c4
-rw-r--r--tests/libtest/lib516.c4
-rw-r--r--tests/libtest/lib517.c4
-rw-r--r--tests/libtest/lib518.c4
-rw-r--r--tests/libtest/lib519.c2
-rw-r--r--tests/libtest/lib520.c4
-rw-r--r--tests/libtest/lib521.c2
-rw-r--r--tests/libtest/lib523.c2
-rw-r--r--tests/libtest/lib524.c2
-rw-r--r--tests/libtest/lib525.c4
-rw-r--r--tests/libtest/lib526.c4
-rw-r--r--tests/libtest/lib530.c4
-rw-r--r--tests/libtest/lib533.c4
-rw-r--r--tests/libtest/lib537.c4
-rw-r--r--tests/libtest/lib539.c4
-rw-r--r--tests/libtest/lib540.c4
-rw-r--r--tests/libtest/lib541.c6
-rw-r--r--tests/libtest/lib542.c4
-rw-r--r--tests/libtest/lib543.c2
-rw-r--r--tests/libtest/lib544.c4
-rw-r--r--tests/libtest/lib547.c2
-rw-r--r--tests/libtest/lib549.c2
-rw-r--r--tests/libtest/lib552.c4
-rw-r--r--tests/libtest/lib553.c2
-rw-r--r--tests/libtest/lib554.c4
-rw-r--r--tests/libtest/lib555.c4
-rw-r--r--tests/libtest/lib556.c6
-rw-r--r--tests/libtest/lib557.c2
-rw-r--r--tests/libtest/lib558.c2
-rw-r--r--tests/libtest/lib559.c2
-rw-r--r--tests/libtest/lib560.c2
-rw-r--r--tests/libtest/lib562.c4
-rw-r--r--tests/libtest/lib564.c4
-rw-r--r--tests/libtest/lib566.c2
-rw-r--r--tests/libtest/lib567.c2
-rw-r--r--tests/libtest/lib568.c2
-rw-r--r--tests/libtest/lib569.c4
-rw-r--r--tests/libtest/lib570.c8
-rw-r--r--tests/libtest/lib571.c4
-rw-r--r--tests/libtest/lib572.c2
-rw-r--r--tests/libtest/lib573.c2
-rw-r--r--tests/libtest/lib574.c4
-rw-r--r--tests/libtest/lib575.c4
-rw-r--r--tests/libtest/lib576.c2
-rw-r--r--tests/libtest/lib578.c4
-rw-r--r--tests/libtest/lib579.c2
-rw-r--r--tests/libtest/lib582.c2
-rw-r--r--tests/libtest/lib583.c15
-rw-r--r--tests/libtest/lib586.c2
-rw-r--r--tests/libtest/lib589.c4
-rw-r--r--tests/libtest/lib590.c4
-rw-r--r--tests/libtest/lib591.c2
-rw-r--r--tests/libtest/lib597.c4
-rw-r--r--tests/libtest/lib598.c2
-rw-r--r--tests/libtest/lib599.c4
-rw-r--r--tests/libtest/lib643.c2
-rw-r--r--tests/libtest/lib650.c4
-rw-r--r--tests/libtest/lib651.c2
-rw-r--r--tests/libtest/lib652.c2
-rw-r--r--tests/libtest/lib653.c4
-rw-r--r--tests/libtest/lib654.c2
-rw-r--r--tests/libtest/lib655.c4
-rw-r--r--tests/libtest/lib658.c4
-rw-r--r--tests/libtest/lib659.c4
-rw-r--r--tests/libtest/lib661.c4
-rw-r--r--tests/libtest/lib666.c2
-rw-r--r--tests/libtest/lib667.c2
-rw-r--r--tests/libtest/lib668.c2
-rw-r--r--tests/libtest/lib670.c2
-rw-r--r--tests/libtest/lib674.c2
-rw-r--r--tests/libtest/libauthretry.c4
-rw-r--r--tests/libtest/libntlmconnect.c4
-rwxr-xr-xtests/libtest/mk-lib1521.pl18
-rwxr-xr-xtests/libtest/notexists.pl2
-rw-r--r--tests/libtest/sethostname.c2
-rw-r--r--tests/libtest/sethostname.h4
-rw-r--r--tests/libtest/stub_gssapi.c4
-rw-r--r--tests/libtest/stub_gssapi.h2
-rw-r--r--tests/libtest/test.h48
-rwxr-xr-xtests/libtest/test1013.pl2
-rwxr-xr-xtests/libtest/test1022.pl2
-rwxr-xr-xtests/libtest/test307.pl2
-rwxr-xr-xtests/libtest/test610.pl2
-rwxr-xr-xtests/libtest/test613.pl2
-rw-r--r--tests/libtest/testtrace.c4
-rw-r--r--tests/libtest/testtrace.h2
-rw-r--r--tests/libtest/testutil.c2
-rw-r--r--tests/libtest/testutil.h2
-rwxr-xr-xtests/manpage-scan.pl.in2
-rwxr-xr-xtests/mem-include-scan.pl.in2
-rwxr-xr-xtests/memanalyze.pl.in4
-rwxr-xr-xtests/negtelnetserver.py.in10
-rwxr-xr-xtests/nroff-scan.pl.in2
-rwxr-xr-xtests/objnames-test08.sh217
-rwxr-xr-xtests/objnames-test10.sh217
-rw-r--r--tests/objnames.inc107
-rw-r--r--tests/options-scan.pl6
-rw-r--r--tests/pathhelp.pm2
-rwxr-xr-xtests/rtspserver.pl.in2
-rw-r--r--tests/runtests.12
-rwxr-xr-xtests/runtests.pl.in195
-rwxr-xr-xtests/secureserver.pl.in2
-rw-r--r--tests/server/CMakeLists.txt2
-rw-r--r--tests/server/Makefile.am4
-rw-r--r--tests/server/Makefile.inc2
-rwxr-xr-xtests/server/base64.pl2
-rw-r--r--tests/server/disabled.c4
-rw-r--r--tests/server/fake_ntlm.c2
-rw-r--r--tests/server/getpart.c2
-rw-r--r--tests/server/getpart.h2
-rw-r--r--tests/server/mqttd.c9
-rw-r--r--tests/server/resolve.c2
-rw-r--r--tests/server/rtspd.c2
-rw-r--r--tests/server/server_setup.h2
-rw-r--r--tests/server/server_sockaddr.h2
-rw-r--r--tests/server/sockfilt.c8
-rw-r--r--tests/server/socksd.c2
-rw-r--r--tests/server/sws.c2
-rw-r--r--tests/server/testpart.c2
-rw-r--r--tests/server/tftp.h2
-rw-r--r--tests/server/tftpd.c15
-rw-r--r--tests/server/util.c13
-rw-r--r--tests/server/util.h2
-rw-r--r--tests/serverhelp.pm2
-rwxr-xr-xtests/smbserver.py.in24
-rw-r--r--tests/sshhelp.pm2
-rw-r--r--tests/sshserver.pl.in2
-rwxr-xr-xtests/symbol-scan.pl.in4
-rw-r--r--tests/testcurl.18
-rwxr-xr-xtests/testcurl.pl.in14
-rwxr-xr-xtests/tftpserver.pl.in2
-rw-r--r--tests/unit/CMakeLists.txt2
-rw-r--r--tests/unit/Makefile.am6
-rw-r--r--tests/unit/Makefile.inc7
-rw-r--r--tests/unit/README.md (renamed from tests/unit/README)42
-rw-r--r--tests/unit/curlcheck.h2
-rw-r--r--tests/unit/unit1300.c32
-rw-r--r--tests/unit/unit1301.c4
-rw-r--r--tests/unit/unit1302.c2
-rw-r--r--tests/unit/unit1303.c4
-rw-r--r--tests/unit/unit1304.c4
-rw-r--r--tests/unit/unit1305.c4
-rw-r--r--tests/unit/unit1307.c4
-rw-r--r--tests/unit/unit1308.c4
-rw-r--r--tests/unit/unit1309.c4
-rw-r--r--tests/unit/unit1323.c4
-rw-r--r--tests/unit/unit1330.c2
-rw-r--r--tests/unit/unit1394.c2
-rw-r--r--tests/unit/unit1395.c2
-rw-r--r--tests/unit/unit1396.c4
-rw-r--r--tests/unit/unit1397.c4
-rw-r--r--tests/unit/unit1398.c4
-rw-r--r--tests/unit/unit1399.c4
-rw-r--r--tests/unit/unit1600.c2
-rw-r--r--tests/unit/unit1601.c2
-rw-r--r--tests/unit/unit1602.c6
-rw-r--r--tests/unit/unit1603.c6
-rw-r--r--tests/unit/unit1604.c4
-rw-r--r--tests/unit/unit1605.c2
-rw-r--r--tests/unit/unit1606.c4
-rw-r--r--tests/unit/unit1607.c4
-rw-r--r--tests/unit/unit1608.c2
-rw-r--r--tests/unit/unit1609.c4
-rw-r--r--tests/unit/unit1610.c2
-rw-r--r--tests/unit/unit1611.c2
-rw-r--r--tests/unit/unit1612.c2
-rw-r--r--tests/unit/unit1620.c2
-rw-r--r--tests/unit/unit1621.c4
-rw-r--r--tests/unit/unit1650.c2
-rw-r--r--tests/unit/unit1651.c4
-rw-r--r--tests/unit/unit1652.c4
-rw-r--r--tests/unit/unit1653.c44
-rw-r--r--tests/unit/unit1654.c17
-rw-r--r--tests/unit/unit1655.c2
-rw-r--r--tests/unit/unit1660.c171
-rwxr-xr-xtests/util.py (renamed from tests/curl_test_data.py.in)35
-rw-r--r--tests/valgrind.pm2
-rw-r--r--tests/valgrind.supp32
-rwxr-xr-xtests/version-scan.pl.in2
-rw-r--r--winbuild/README.md132
2355 files changed, 15662 insertions, 15131 deletions
diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml
index 82a590eb6..3e474cfe2 100644
--- a/.azure-pipelines.yml
+++ b/.azure-pipelines.yml
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -73,7 +73,7 @@ stages:
torture:
name: torture
install: libnghttp2-dev
- configure: --enable-debug --disable-shared --disable-threaded-resolver --enable-alt-svc
+ configure: --enable-debug --disable-shared --disable-threaded-resolver
tests: -n -t --shallow=40 !FTP
steps:
- script: sudo apt-get update && sudo apt-get install -y stunnel4 python-impacket libzstd-dev libbrotli-dev $(install)
@@ -83,7 +83,7 @@ stages:
displayName: 'configure $(name)'
- script: make
- displayName: 'make'
+ displayName: 'make && cd tests && make'
- script: make test-nonflaky
displayName: 'test'
@@ -117,15 +117,15 @@ stages:
container_img: mback2k/curl-docker-winbuildenv-msys2-mingw32:ltsc2019
container_cmd: C:\msys64\usr\bin\sh
prepare: pacman -S --needed --noconfirm --noprogressbar libssh2-devel mingw-w64-i686-libssh2
- configure: --host=i686-w64-mingw32 --build=i686-w64-mingw32 --prefix=/mingw32 --enable-debug --enable-werror --enable-mqtt --with-libssh2
- tests: ~612 ~1056 ~1299 !SCP
+ configure: --host=i686-w64-mingw32 --build=i686-w64-mingw32 --prefix=/mingw32 --enable-debug --enable-werror --with-libssh2
+ tests: ~571 ~612 ~1056 ~1299 !SCP
msys2_mingw64_debug_openssl:
name: 64-bit OpenSSL and MQTT
container_img: mback2k/curl-docker-winbuildenv-msys2-mingw64:ltsc2019
container_cmd: C:\msys64\usr\bin\sh
prepare: pacman -S --needed --noconfirm --noprogressbar libssh2-devel mingw-w64-x86_64-libssh2
- configure: --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --prefix=/mingw64 --enable-debug --enable-werror --enable-mqtt --with-libssh2
- tests: ~612 ~1056 ~1299 !SCP
+ configure: --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --prefix=/mingw64 --enable-debug --enable-werror --with-libssh2
+ tests: ~571 ~612 ~1056 ~1299 !SCP
msys1_mingw_debug_openssl:
name: 32-bit OpenSSL (legacy)
container_img: mback2k/curl-docker-winbuildenv-msys1-mingw:ltsc2019
@@ -150,32 +150,32 @@ stages:
container_cmd: C:\msys64\usr\bin\sh
prepare: pacman -S --needed --noconfirm --noprogressbar libssh2-devel mingw-w64-i686-libssh2
configure: --host=i686-w64-mingw32 --build=i686-w64-mingw32 --prefix=/mingw32 --enable-debug --enable-werror --enable-sspi --without-ssl --with-schannel --with-winidn --with-libssh2
- tests: ~165 ~310 ~612 ~1013 ~1056 ~1299 ~1448 ~2034 ~2037 ~2041 ~2046 ~2047 ~3000 ~3001 !SCP
+ tests: ~165 ~310 ~571 ~612 ~1056 ~1299 ~1448 ~2034 ~2037 ~2041 ~2046 ~2047 ~3000 ~3001 !SCP
msys2_mingw64_debug_schannel:
name: 64-bit Schannel/SSPI/WinIDN
container_img: mback2k/curl-docker-winbuildenv-msys2-mingw64:ltsc2019
container_cmd: C:\msys64\usr\bin\sh
prepare: pacman -S --needed --noconfirm --noprogressbar libssh2-devel mingw-w64-x86_64-libssh2
configure: --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --prefix=/mingw64 --enable-debug --enable-werror --enable-sspi --without-ssl --with-schannel --with-winidn --with-libssh2
- tests: ~165 ~310 ~612 ~1013 ~1056 ~1299 ~1448 ~2034 ~2037 ~2041 ~2046 ~2047 ~3000 ~3001 !SCP
+ tests: ~165 ~310 ~571 ~612 ~1056 ~1299 ~1448 ~2034 ~2037 ~2041 ~2046 ~2047 ~3000 ~3001 !SCP
msys1_mingw_debug_schannel:
name: 32-bit Schannel/SSPI/WinIDN (legacy)
container_img: mback2k/curl-docker-winbuildenv-msys1-mingw:ltsc2019
container_cmd: C:\MinGW\msys\1.0\bin\sh
configure: --host=i686-pc-mingw32 --build=i686-pc-mingw32 --prefix=/mingw --enable-debug --enable-sspi --without-ssl --with-schannel --with-winidn
- tests: ~203 ~305 ~310 ~311 ~312 ~313 ~404 ~1013 ~1056 ~1143 ~2034 ~2035 ~2037 ~2038 ~2041 ~2042 ~2048 ~3000 ~3001
+ tests: ~203 ~305 ~310 ~311 ~312 ~313 ~404 ~1056 ~1143 ~2034 ~2035 ~2037 ~2038 ~2041 ~2042 ~2048 ~3000 ~3001
msys1_mingw32_debug_schannel:
name: 32-bit Schannel/SSPI/WinIDN w/o zlib
container_img: mback2k/curl-docker-winbuildenv-msys1-mingw32:ltsc2019
container_cmd: C:\MinGW\msys\1.0\bin\sh
configure: --host=i686-w64-mingw32 --build=i686-w64-mingw32 --prefix=/mingw32 --enable-debug --enable-werror --enable-sspi --without-ssl --with-schannel --with-winidn --without-zlib
- tests: ~203 ~310 ~1013 ~1056 ~1143 ~1299 ~2034 ~2037 ~2041 ~3000 ~3001
+ tests: ~203 ~310 ~1056 ~1143 ~1299 ~2034 ~2037 ~2041 ~3000 ~3001
msys1_mingw64_debug_schannel:
name: 64-bit Schannel/SSPI/WinIDN w/o zlib
container_img: mback2k/curl-docker-winbuildenv-msys1-mingw64:ltsc2019
container_cmd: C:\MinGW\msys\1.0\bin\sh
configure: --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --prefix=/mingw64 --enable-debug --enable-werror --enable-sspi --without-ssl --with-schannel --with-winidn --without-zlib
- tests: ~203 ~310 ~1013 ~1056 ~1143 ~1299 ~2034 ~2037 ~2041 ~3000 ~3001
+ tests: ~203 ~310 ~1056 ~1143 ~1299 ~2034 ~2037 ~2041 ~3000 ~3001
container:
image: $(container_img)
env:
@@ -188,11 +188,14 @@ stages:
- script: $(container_cmd) -l -c "cd $(echo '%cd%') && ./buildconf && ./configure $(configure)"
displayName: 'configure $(name)'
- - script: $(container_cmd) -l -c "cd $(echo '%cd%') && make"
+ - script: $(container_cmd) -l -c "cd $(echo '%cd%') && make && cd tests && make"
displayName: 'make'
+ - script: $(container_cmd) -l -c "cd $(echo '%cd%') && make install && PATH=/usr/bin:/bin find . -type f -path '*/.libs/*.exe' -print -execdir mv -t .. {} \;"
+ displayName: 'install'
+
- script: $(container_cmd) -l -c "cd $(echo '%cd%') && make test-nonflaky"
displayName: 'test'
env:
AZURE_ACCESS_TOKEN: "$(System.AccessToken)"
- TFLAGS: "-r $(tests)"
+ TFLAGS: "-vc /usr/bin/curl.exe -r $(tests)"
diff --git a/.cirrus.yml b/.cirrus.yml
index a1cd12a5a..a88ed7bd1 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -28,6 +28,7 @@ task:
matrix:
# A stable 13.0 image likely won't be available before early 2021
# image_family: freebsd-13-0-snap
+ image_family: freebsd-12-2
image_family: freebsd-12-1
image_family: freebsd-11-4
@@ -63,15 +64,8 @@ task:
# Some tests won't run if run as root so run them as another user.
# Make directories world writable so the test step can write wherever it needs.
- find . -type d -exec chmod 777 {} \;
- # TODO: A number of tests are failing on different FreeBSD versions and so
- # are disabled. This should be investigated.
- - SKIP_TESTS=''
- - uname -r
- - case `uname -r` in
- 13.0*) SKIP_TESTS='!SFTP !SCP';;
- 12.1*) SKIP_TESTS='!SFTP !SCP';;
- 11.*) SKIP_TESTS='!SFTP !SCP';;
- esac
- - sudo -u nobody make V=1 TFLAGS="-n -a -p !flaky ${SKIP_TESTS}" test-nonflaky
+ # The OpenSSH server instance for the testsuite cannot be started on FreeBSD,
+ # therefore the SFTP and SCP tests are disabled right away from the beginning.
+ - sudo -u nobody make V=1 TFLAGS="-n -a -p !flaky !SFTP !SCP" test-nonflaky
install_script:
- make V=1 install
diff --git a/.dir-locals.el b/.dir-locals.el
index 7c209357d..06dc613f2 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -9,7 +9,7 @@
;;;
;;; This software is licensed as described in the file COPYING, which
;;; you should have received as part of this distribution. The terms
-;;; are also available at https://curl.haxx.se/docs/copyright.html.
+;;; are also available at https://curl.se/docs/copyright.html.
;;;
;;; You may opt to use, copy, modify, merge, publish, distribute and/or sell
;;; copies of the Software, and permit persons to whom the Software is
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 000000000..b16554c6e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,11 @@
+blank_issues_enabled: false
+contact_links:
+ - name: Feature request
+ url: https://curl.se/mail/
+ about: To propose new features or enhancements, please bring that discussion to a suitable curl mailing list.
+ - name: Question
+ url: https://curl.se/mail/
+ about: Questions should go to the mailing list
+ - name: Commercial support
+ url: https://curl.se/support.html
+ about: Several companies are offering paid support for curl/libcurl
diff --git a/.lgtm.yml b/.lgtm.yml
index 4063cd3a7..c97528684 100644
--- a/.lgtm.yml
+++ b/.lgtm.yml
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/.mailmap b/.mailmap
index 15024a240..367dc9c6e 100644
--- a/.mailmap
+++ b/.mailmap
@@ -5,8 +5,8 @@ Alessandro Ghedini <alessandro@ghedini.me> <alessandro@cloudflare.com>
Alessandro Ghedini <alessandro@ghedini.me> <al3xbio@gmail.com>
Björn Stenberg <bjorn@haxx.se>
Björn Stenberg <bjorn@haxx.se> <bjst@bjorn>
-Viktor Szakats <commit@vszakats.net>
-Viktor Szakats <commit@vszakats.net> <vszakats@users.noreply.github.com>
+Viktor Szakats <commit@vsz.me> <commit@vszakats.net>
+Viktor Szakats <commit@vsz.me> <vszakats@users.noreply.github.com>
Daniel Gustafsson <daniel@yesql.se> <dgustafsson@pivotal.io>
Daniel Gustafsson <daniel@yesql.se> <daniel@hobbit.se>
Linus Nielsen <linus@haxx.se>
@@ -72,3 +72,9 @@ Douglas Steinwand <dzs-curl@dzs.fx.org>
James Fuller <jim@webcomposite.com>
Don J Olmstead <don.j.olmstead@gmail.com>
Nicolas Sterchele <sterchelen@gmail.com>
+Sergey Raevskiy <ccik@inbox.ru>
+SecuritySense on github <si@securitysense.co.uk>
+Mipsters on github <tomaviv57@gmail.com>
+Pavel Novikov <paul.skeptic@yandex.ru>
+apique13 on github <apique@PC42.isdom.isoft.fr>
+Daniel Hwang <danielleehwang@gmail.com>
diff --git a/.travis.yml b/.travis.yml
index db47499fc..9ce8ee441 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -27,231 +27,98 @@ env:
- LD_LIBRARY_PATH=/usr/local/lib
addons:
- apt:
- config:
- retries: true
- sources: &common_sources
- - ubuntu-toolchain-r-test
- packages: &common_packages
- - cmake
- - gcc-8
- - valgrind
- - libev-dev
- - libc-ares-dev
- - g++-8
- - libstdc++-8-dev
- - stunnel4
- - libidn2-0-dev
- - gnutls-bin
- - libgnutls28-dev
- - python-impacket
- - pax
- - ncompress
+ apt: &common_apt
+ config:
+ retries: true
+ packages: &common_packages
+ - cmake
+ - valgrind
+ - libev-dev
+ - libc-ares-dev
+ - g++-8
+ - libstdc++-8-dev
+ - stunnel4
+ - libidn2-dev
+ - gnutls-bin
+ - libgnutls28-dev
+ - python-impacket
+ - ninja-build
+ - pax
+ - ncompress
-matrix:
- include:
- - os: linux
- compiler: gcc
- dist: trusty
- env:
- - T=normal C="" CHECKSRC=1
- - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
- - os: linux
- compiler: gcc
- dist: trusty
- env:
- - T=normal C="--enable-mqtt"
- - os: linux
- compiler: gcc
- dist: bionic
- env:
- - T=normal C="--disable-verbose" CPPFLAGS="-Wno-variadic-macros" NOTESTS=1
- - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
- - os: linux
- compiler: gcc
- dist: bionic
- before_install:
- # Install and use the current stable release of Go
- - gimme --list
- - eval "$(gimme stable)"
- - gimme --list
- env:
- - T=novalgrind C=""
- - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
- addons:
- apt:
- sources:
- - ppa:longsleep/golang-backports
- - *common_sources
- packages:
- - *common_packages
- - os: linux
- compiler: gcc
- dist: xenial
- env:
- - T=novalgrind C="--enable-alt-svc" NOTESTS=
- - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
- - os: linux
- compiler: clang
- dist: xenial
- env:
- - T=debug
- - OVERRIDE_CC="CC=clang-7" OVERRIDE_CXX="CXX=clang++-7"
- addons:
- apt:
- sources:
- - *common_sources
- - llvm-toolchain-xenial-7
- packages:
- - *common_packages
- - clang-7
- - os: linux
- compiler: clang
- dist: xenial
- env:
- - T=debug C="--enable-alt-svc"
- - OVERRIDE_CC="CC=clang-7" OVERRIDE_CXX="CXX=clang++-7"
- addons:
- apt:
- sources:
- - *common_sources
- - llvm-toolchain-xenial-7
- packages:
- - *common_packages
- - clang-7
- - os: linux
- compiler: clang
- dist: bionic
- env:
- - T=debug C="--with-gnutls --without-ssl"
- - OVERRIDE_CC="CC=clang-7" OVERRIDE_CXX="CXX=clang++-7"
- addons:
- apt:
- sources:
- - *common_sources
- - llvm-toolchain-bionic-7
- packages:
- - *common_packages
- - clang-7
- - os: linux
- compiler: gcc
- dist: trusty
- env:
- - T=iconv
- - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
- - os: linux
- compiler: gcc
- dist: bionic
- env:
- - T=cmake
- - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
- - os: linux
- compiler: clang
- dist: bionic
- env:
- - T=cmake
- - OVERRIDE_CC="CC=clang-7" OVERRIDE_CXX="CXX=clang++-7"
- addons:
- apt:
- sources:
- - *common_sources
- - llvm-toolchain-bionic-7
- packages:
- - *common_packages
- - clang-7
- - os: linux
- compiler: gcc
- dist: xenial
- env:
- - T=torture
- - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
- addons:
- apt:
- sources:
- - *common_sources
- packages:
- - *common_packages
- - lcov
- - os: linux
- compiler: gcc
- dist: bionic
- env:
- - T=distcheck
- - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
- - os: linux
- compiler: clang
- dist: bionic
- env:
- - T=fuzzer
- - OVERRIDE_CC="CC=clang-7" OVERRIDE_CXX="CXX=clang++-7"
- addons:
- apt:
- sources:
- - *common_sources
- - llvm-toolchain-bionic-7
- packages:
- - *common_packages
- - clang-7
- - os: linux
- compiler: clang
- dist: bionic
- env:
- - T=tidy
- - OVERRIDE_CC="CC=clang-7" OVERRIDE_CXX="CXX=clang++-7"
- addons:
- apt:
- sources:
- - *common_sources
- - llvm-toolchain-bionic-7
- packages:
- - *common_packages
- - clang-7
- - clang-tidy-7
- - os: linux
- compiler: clang
- dist: bionic
- env:
- - T=scan-build
- - OVERRIDE_CC="CC=clang-7" OVERRIDE_CXX="CXX=clang++-7"
- addons:
- apt:
- sources:
- - *common_sources
- - llvm-toolchain-bionic-7
- packages:
- - *common_packages
- - clang-7
- - os: linux
- compiler: clang
- dist: xenial
- env:
- - T=debug CFLAGS="-fsanitize=address,undefined,signed-integer-overflow -fno-sanitize-recover=undefined,integer -Wformat -Werror=format-security -Werror=array-bounds -g" LDFLAGS="-fsanitize=address,undefined -fno-sanitize-recover=undefined,integer" LIBS="-ldl -lubsan"
- - OVERRIDE_CC="CC=clang-7" OVERRIDE_CXX="CXX=clang++-7"
- addons:
- apt:
- sources:
- - *common_sources
- - llvm-toolchain-xenial-7
- packages:
- - *common_packages
- - clang-7
- - os: linux
- arch: arm64
- compiler: gcc
- dist: bionic
- env:
- - T=debug C="--enable-alt-svc"
- - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
- addons:
- apt:
- sources:
- - *common_sources
- packages:
- - *common_packages
- - libev-dev
- - libtool
- - pkg-config
- - zlib1g-dev
+jobs:
+ include:
+ - env:
+ - T=normal C="" CHECKSRC=1
+ - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
+ - env:
+ - T=normal C="--disable-verbose" CPPFLAGS="-Wno-variadic-macros" NOTESTS=1
+ - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
+ - env:
+ - T=debug
+ - &clang OVERRIDE_CC="CC=clang-9" OVERRIDE_CXX="CXX=clang++-9"
+ compiler: clang
+ addons:
+ apt:
+ <<: *common_apt
+ packages:
+ - &clang_packages [*common_packages, clang-9]
+ - env:
+ - T=debug C="--enable-hsts --disable-alt-svc"
+ - *clang
+ compiler: clang
+ addons:
+ apt:
+ <<: *common_apt
+ packages:
+ - *clang_packages
+ - env:
+ - T=debug C="--with-gnutls --without-ssl"
+ - *clang
+ compiler: clang
+ addons:
+ apt:
+ <<: *common_apt
+ packages:
+ - *clang_packages
+ - env:
+ - T=iconv
+ - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
+ - env:
+ - T=torture
+ - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
+ addons:
+ apt:
+ <<: *common_apt
+ packages:
+ - *common_packages
+ - lcov
+ - env:
+ - T=distcheck
+ - OVERRIDE_CC="CC=gcc-8" OVERRIDE_CXX="CXX=g++-8"
+ addons:
+ apt:
+ <<: *common_apt
+ packages:
+ - *common_packages
+ - env:
+ - T=scan-build
+ - *clang
+ compiler: clang
+ addons:
+ apt:
+ <<: *common_apt
+ packages:
+ - *clang_packages
+ - env:
+ - T=debug CFLAGS="-fsanitize=address,undefined,signed-integer-overflow -fno-sanitize-recover=undefined,integer -Wformat -Werror=format-security -Werror=array-bounds -g" LDFLAGS="-fsanitize=address,undefined -fno-sanitize-recover=undefined,integer" LIBS="-ldl -lubsan" TFLAGS=-n
+ - *clang
+ compiler: clang
+ addons:
+ apt:
+ <<: *common_apt
+ packages:
+ - *clang_packages
before_install:
- export "${OVERRIDE_CC-blank=}"
diff --git a/CHANGES b/CHANGES
index 4d13ef696..3e2cd9947 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,4 @@
-See https://curl.haxx.se/changes.html for the edited and human readable online
+See https://curl.se/changes.html for the edited and human readable online
version of what has changed over the years in different curl releases.
Generate a CHANGES file like the one present in every release like this:
diff --git a/CMake/CMakeConfigurableFile.in b/CMake/CMakeConfigurableFile.in
index 2bafe2c10..8ccd016a6 100644
--- a/CMake/CMakeConfigurableFile.in
+++ b/CMake/CMakeConfigurableFile.in
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/CurlSymbolHiding.cmake b/CMake/CurlSymbolHiding.cmake
index aaac9fead..e99ea6f64 100644
--- a/CMake/CurlSymbolHiding.cmake
+++ b/CMake/CurlSymbolHiding.cmake
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -27,7 +27,7 @@ mark_as_advanced(CURL_HIDDEN_SYMBOLS)
if(CURL_HIDDEN_SYMBOLS)
set(SUPPORTS_SYMBOL_HIDING FALSE)
- if(CMAKE_C_COMPILER_ID MATCHES "Clang")
+ if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT MSVC)
set(SUPPORTS_SYMBOL_HIDING TRUE)
set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
diff --git a/CMake/CurlTests.c b/CMake/CurlTests.c
index 3ef35f025..949910d5e 100644
--- a/CMake/CurlTests.c
+++ b/CMake/CurlTests.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/FindBearSSL.cmake b/CMake/FindBearSSL.cmake
index a8f72c92d..9455f4ba3 100644
--- a/CMake/FindBearSSL.cmake
+++ b/CMake/FindBearSSL.cmake
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/FindGSS.cmake b/CMake/FindGSS.cmake
index 02111a20f..4e4747d6c 100644
--- a/CMake/FindGSS.cmake
+++ b/CMake/FindGSS.cmake
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/FindNGHTTP3.cmake b/CMake/FindNGHTTP3.cmake
index 73ce9e188..643b60097 100644
--- a/CMake/FindNGHTTP3.cmake
+++ b/CMake/FindNGHTTP3.cmake
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/FindNGTCP2.cmake b/CMake/FindNGTCP2.cmake
index a1ed8cd4b..5757009a5 100644
--- a/CMake/FindNGTCP2.cmake
+++ b/CMake/FindNGTCP2.cmake
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/FindNSS.cmake b/CMake/FindNSS.cmake
index 5fdb2b776..899c6b075 100644
--- a/CMake/FindNSS.cmake
+++ b/CMake/FindNSS.cmake
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/FindQUICHE.cmake b/CMake/FindQUICHE.cmake
index 01d17582b..0247364d4 100644
--- a/CMake/FindQUICHE.cmake
+++ b/CMake/FindQUICHE.cmake
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/FindWolfSSL.cmake b/CMake/FindWolfSSL.cmake
index 54df1a86c..42256b3cd 100644
--- a/CMake/FindWolfSSL.cmake
+++ b/CMake/FindWolfSSL.cmake
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/FindZstd.cmake b/CMake/FindZstd.cmake
index 44c741ae8..eaba39746 100644
--- a/CMake/FindZstd.cmake
+++ b/CMake/FindZstd.cmake
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/Macros.cmake b/CMake/Macros.cmake
index e11f11155..b9fd33e8d 100644
--- a/CMake/Macros.cmake
+++ b/CMake/Macros.cmake
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -107,3 +107,14 @@ macro(curl_nroff_check)
message(WARNING "Found no *nroff program")
endif()
endmacro()
+
+macro(optional_dependency DEPENDENCY)
+ set(CURL_${DEPENDENCY} AUTO CACHE STRING "Build curl with ${DEPENDENCY} support (AUTO, ON or OFF)")
+ set_property(CACHE CURL_${DEPENDENCY} PROPERTY STRINGS AUTO ON OFF)
+
+ if(CURL_${DEPENDENCY} STREQUAL AUTO)
+ find_package(${DEPENDENCY})
+ elseif(CURL_${DEPENDENCY})
+ find_package(${DEPENDENCY} REQUIRED)
+ endif()
+endmacro()
diff --git a/CMake/OtherTests.cmake b/CMake/OtherTests.cmake
index 7cec6da6d..80c0b7275 100644
--- a/CMake/OtherTests.cmake
+++ b/CMake/OtherTests.cmake
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/Platforms/WindowsCache.cmake b/CMake/Platforms/WindowsCache.cmake
index 9ae9b56f0..12cec52dc 100644
--- a/CMake/Platforms/WindowsCache.cmake
+++ b/CMake/Platforms/WindowsCache.cmake
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/Utilities.cmake b/CMake/Utilities.cmake
index 59b17d074..8f9b861ba 100644
--- a/CMake/Utilities.cmake
+++ b/CMake/Utilities.cmake
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/cmake_uninstall.cmake.in b/CMake/cmake_uninstall.cmake.in
index 4a0de5e6b..e96c1432a 100644
--- a/CMake/cmake_uninstall.cmake.in
+++ b/CMake/cmake_uninstall.cmake.in
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/gnurl-config.cmake.in b/CMake/gnurl-config.cmake.in
index 240c3a96e..aa58ed3b9 100644
--- a/CMake/gnurl-config.cmake.in
+++ b/CMake/gnurl-config.cmake.in
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 687929a79..8696fee5a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -49,7 +49,8 @@ project(GNURL C)
message(WARNING "the curl cmake build system is poorly maintained. Be aware")
-file(STRINGS $GNURL_SOURCE_DIR}/include/gnurl/curlver.h CURL_VERSION_H_CONTENTS REGEX "#define LIBCURL_VERSION( |_NUM )")
+file(STRINGS ${GNURL_SOURCE_DIR}/include/gnurl/curlver.h CURL_VERSION_H_CONTENTS REGEX "#define LIBCURL_VERSION( |_NUM )")
+
string(REGEX MATCH "#define LIBCURL_VERSION \"[^\"]*"
CURL_VERSION ${CURL_VERSION_H_CONTENTS})
string(REGEX REPLACE "[^\"]+\"" "" CURL_VERSION ${CURL_VERSION})
@@ -65,7 +66,7 @@ message(STATUS "gnurl version=[${CURL_VERSION}]")
# SET(PACKAGE_NAME "curl")
# SET(PACKAGE_VERSION "-")
# SET(PACKAGE_STRING "curl-")
-# SET(PACKAGE_BUGREPORT "a suitable curl mailing list => https://curl.haxx.se/mail/")
+# SET(PACKAGE_BUGREPORT "a suitable curl mailing list => https://curl.se/mail/")
set(OPERATING_SYSTEM "${CMAKE_SYSTEM_NAME}")
set(OS "\"${CMAKE_SYSTEM_NAME}\"")
@@ -79,6 +80,7 @@ option(ENABLE_ARES "Set to ON to enable c-ares support" OFF)
if(WIN32)
option(CURL_STATIC_CRT "Set to ON to build libcurl with static CRT on Windows (/MT)." OFF)
option(ENABLE_INET_PTON "Set to OFF to prevent usage of inet_pton when building against modern SDKs while still requiring compatibility with older Windows versions, such as Windows XP, Windows Server 2003 etc." ON)
+ option(ENABLE_UNICODE "Set to ON to use the Unicode version of the Windows API functions" OFF)
set(CURL_TARGET_WINDOWS_VERSION "" CACHE STRING "Minimum target Windows version as hex string")
if(CURL_TARGET_WINDOWS_VERSION)
add_definitions(-D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION})
@@ -92,6 +94,12 @@ if(WIN32)
add_definitions(-D_WIN32_WINNT=0x0501)
set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_WIN32_WINNT=0x0501")
endif()
+ if(ENABLE_UNICODE)
+ add_definitions(-DUNICODE -D_UNICODE)
+ if(MINGW)
+ add_compile_options(-municode)
+ endif()
+ endif()
endif()
option(CURL_LTO "Turn on compiler Link Time Optimizations" OFF)
@@ -195,28 +203,30 @@ mark_as_advanced(CURL_DISABLE_SMTP)
option(CURL_DISABLE_GOPHER "to disable Gopher" ON)
mark_as_advanced(CURL_DISABLE_GOPHER)
-option(CURL_ENABLE_MQTT "to enable MQTT" OFF)
-mark_as_advanced(CURL_ENABLE_MQTT)
+option(CURL_DISABLE_MQTT "to disable MQTT" OFF)
+mark_as_advanced(CURL_DISABLE_MQTT)
if(HTTP_ONLY)
+ set(CURL_DISABLE_DICT ON)
+ set(CURL_DISABLE_FILE ON)
set(CURL_DISABLE_FTP ON)
+ set(CURL_DISABLE_GOPHER ON)
+ set(CURL_DISABLE_IMAP ON)
set(CURL_DISABLE_LDAP ON)
set(CURL_DISABLE_LDAPS ON)
- set(CURL_DISABLE_TELNET ON)
- set(CURL_DISABLE_DICT ON)
- set(CURL_DISABLE_FILE ON)
- set(CURL_DISABLE_TFTP ON)
- set(CURL_DISABLE_RTSP ON)
+ set(CURL_DISABLE_MQTT ON)
set(CURL_DISABLE_POP3 ON)
- set(CURL_DISABLE_IMAP ON)
+ set(CURL_DISABLE_RTSP ON)
set(CURL_DISABLE_SMB ON)
set(CURL_DISABLE_SMTP ON)
- set(CURL_DISABLE_GOPHER ON)
+ set(CURL_DISABLE_TELNET ON)
+ set(CURL_DISABLE_TFTP ON)
endif()
+option(CURL_DISABLE_ALTSVC "to disable alt-svc support" OFF)
+mark_as_advanced(CURL_DISABLE_ALTSVC)
option(CURL_DISABLE_COOKIES "to disable cookies support" OFF)
mark_as_advanced(CURL_DISABLE_COOKIES)
-
option(CURL_DISABLE_CRYPTO_AUTH "to disable cryptographic authentication" OFF)
mark_as_advanced(CURL_DISABLE_CRYPTO_AUTH)
@@ -259,10 +269,6 @@ if(ENABLE_MANUAL)
set(USE_MANUAL ON)
endif()
-# We need ansi c-flags, especially on HP
-set(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}")
-set(CMAKE_REQUIRED_FLAGS ${CMAKE_ANSI_CFLAGS})
-
if(CURL_STATIC_CRT)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT")
@@ -667,28 +673,25 @@ check_library_exists_concat("idn2" idn2_lookup_ul HAVE_LIBIDN2)
# Check for symbol dlopen (same as HAVE_LIBDL)
check_library_exists("${GNURL_LIBS}" dlopen "" HAVE_DLOPEN)
-option(CURL_ZLIB "Set to ON to enable building curl with zlib support." ON)
set(HAVE_LIBZ OFF)
set(HAVE_ZLIB_H OFF)
set(USE_ZLIB OFF)
-if(CURL_ZLIB)
- find_package(ZLIB QUIET)
- if(ZLIB_FOUND)
- set(HAVE_ZLIB_H ON)
- set(HAVE_LIBZ ON)
- set(USE_ZLIB ON)
-
- # Depend on ZLIB via imported targets if supported by the running
- # version of CMake. This allows our dependents to get our dependencies
- # transitively.
- if(NOT CMAKE_VERSION VERSION_LESS 3.4)
- list(APPEND GNURL_LIBS ZLIB::ZLIB)
- else()
- list(APPEND GNURL_LIBS ${ZLIB_LIBRARIES})
- include_directories(${ZLIB_INCLUDE_DIRS})
- endif()
- list(APPEND CMAKE_REQUIRED_INCLUDES ${ZLIB_INCLUDE_DIRS})
+optional_dependency(ZLIB)
+if(ZLIB_FOUND)
+ set(HAVE_ZLIB_H ON)
+ set(HAVE_LIBZ ON)
+ set(USE_ZLIB ON)
+
+ # Depend on ZLIB via imported targets if supported by the running
+ # version of CMake. This allows our dependents to get our dependencies
+ # transitively.
+ if(NOT CMAKE_VERSION VERSION_LESS 3.4)
+ list(APPEND GNURL_LIBS ZLIB::ZLIB)
+ else()
+ list(APPEND GNURL_LIBS ${ZLIB_LIBRARIES})
+ include_directories(${ZLIB_INCLUDE_DIRS})
endif()
+ list(APPEND CMAKE_REQUIRED_INCLUDES ${ZLIB_INCLUDE_DIRS})
endif()
option(CURL_BROTLI "Set to ON to enable building curl with brotli support." OFF)
@@ -770,8 +773,8 @@ if(CMAKE_USE_GSSAPI)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GSS_COMPILER_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${GSS_LINKER_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GSS_LINKER_FLAGS}")
+ set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} ${GSS_LINKER_FLAGS}")
list(APPEND GNURL_LIBS ${GSS_LIBRARIES})
-
else()
message(WARNING "GSSAPI support has been requested but no supporting libraries found. Skipping.")
endif()
@@ -785,8 +788,6 @@ else()
unset(USE_UNIX_SOCKETS CACHE)
endif()
-option(ENABLE_ALT_SVC "Enable alt-svc support" OFF)
-set(USE_ALTSVC ${ENABLE_ALT_SVC})
#
# CA handling
@@ -907,6 +908,7 @@ check_include_file_concat("net/if.h" HAVE_NET_IF_H)
check_include_file_concat("netdb.h" HAVE_NETDB_H)
check_include_file_concat("netinet/in.h" HAVE_NETINET_IN_H)
check_include_file_concat("netinet/tcp.h" HAVE_NETINET_TCP_H)
+check_include_file("linux/tcp.h" HAVE_LINUX_TCP_H)
check_include_file_concat("pem.h" HAVE_PEM_H)
check_include_file_concat("poll.h" HAVE_POLL_H)
@@ -1320,16 +1322,16 @@ if(BUILD_GNURL_EXE)
add_subdirectory(src)
endif()
-option(BUILD_TESTING "Build tests" "${PERL_FOUND}")
-if(NOT PERL_FOUND)
- message(STATUS "Perl not found, testing disabled.")
-elseif(BUILD_TESTING)
+cmake_dependent_option(BUILD_TESTING "Build tests"
+ ON "PERL_FOUND;NOT CURL_DISABLE_TESTS"
+ OFF)
+if(BUILD_TESTING)
add_subdirectory(tests)
endif()
# NTLM support requires crypto function adaptions from various SSL libs
# TODO alternative SSL libs tests for SSP1, GNUTLS, NSS
-if(NOT CURL_DISABLE_CRYPTO_AUTH AND (USE_OPENSSL OR USE_WINDOWS_SSPI OR USE_DARWINSSL OR USE_MBEDTLS OR USE_WIN32_CRYPTO))
+if(NOT CURL_DISABLE_CRYPTO_AUTH AND (USE_OPENSSL OR USE_DARWINSSL OR USE_MBEDTLS OR USE_WIN32_CRYPTO))
set(use_ntlm ON)
else()
set(use_ntlm OFF)
@@ -1348,7 +1350,7 @@ endmacro()
set(_items)
_add_if("SSL" SSL_ENABLED)
_add_if("IPv6" ENABLE_IPV6)
-_add_if("unix-sockets" USE_UNIX_SOCKETS)
+_add_if("unixsockets" USE_UNIX_SOCKETS)
_add_if("libz" HAVE_LIBZ)
_add_if("brotli" HAVE_BROTLI)
_add_if("zstd" HAVE_ZSTD)
@@ -1359,7 +1361,7 @@ _add_if("Largefile" (CURL_SIZEOF_CURL_OFF_T GREATER 4) AND
# TODO SSP1 (Schannel) check is missing
_add_if("SSPI" USE_WINDOWS_SSPI)
_add_if("GSS-API" HAVE_GSSAPI)
-_add_if("alt-svc" ENABLE_ALT_SVC)
+_add_if("alt-svc" NOT CURL_DISABLE_ALTSVC)
# TODO SSP1 missing for SPNEGO
_add_if("SPNEGO" NOT CURL_DISABLE_CRYPTO_AUTH AND
(HAVE_GSSAPI OR USE_WINDOWS_SSPI))
@@ -1367,14 +1369,7 @@ _add_if("Kerberos" NOT CURL_DISABLE_CRYPTO_AUTH AND
(HAVE_GSSAPI OR USE_WINDOWS_SSPI))
# NTLM support requires crypto function adaptions from various SSL libs
# TODO alternative SSL libs tests for SSP1, GNUTLS, NSS
-
-#if(NOT CURL_DISABLE_CRYPTO_AUTH AND (USE_OPENSSL OR USE_WINDOWS_SSPI OR USE_SECTRANSP OR USE_MBEDTLS OR USE_NSS OR USE_GNUTLS))
-# _add_if("NTLM" 1)
-# # TODO missing option (autoconf: --enable-ntlm-wb)
-# _add_if("NTLM_WB" NOT CURL_DISABLE_HTTP AND NTLM_WB_ENABLED)
-#endif()
-
-_add_if("NTLM" use_ntlm)
+_add_if("NTLM" use_ntlm OR USE_WINDOWS_SSPI)
# TODO missing option (autoconf: --enable-ntlm-wb)
_add_if("NTLM_WB" use_ntlm AND NOT CURL_DISABLE_HTTP AND NTLM_WB_ENABLED)
# TODO missing option (--enable-tls-srp), depends on GNUTLS_SRP/OPENSSL_SRP
@@ -1384,6 +1379,7 @@ _add_if("HTTP2" USE_NGHTTP2)
_add_if("HTTP3" USE_NGTCP2 OR USE_QUICHE)
_add_if("MultiSSL" CURL_WITH_MULTI_SSL)
_add_if("HTTPS-proxy" SSL_ENABLED AND (USE_OPENSSL OR USE_GNUTLS OR USE_NSS))
+_add_if("unicode" ENABLE_UNICODE)
string(REPLACE ";" " " SUPPORT_FEATURES "${_items}")
message(STATUS "Enabled features: ${SUPPORT_FEATURES}")
@@ -1416,7 +1412,7 @@ _add_if("SCP" USE_LIBSSH2 OR USE_LIBSSH)
_add_if("SFTP" USE_LIBSSH2 OR USE_LIBSSH)
_add_if("RTSP" NOT CURL_DISABLE_RTSP)
_add_if("RTMP" USE_LIBRTMP)
-_add_if("MQTT" CURL_ENABLE_MQTT)
+_add_if("MQTT" NOT CURL_DISABLE_MQTT)
if(_items)
list(SORT _items)
endif()
diff --git a/MacOSX-Framework b/MacOSX-Framework
index c182fef1f..18e24d658 100755
--- a/MacOSX-Framework
+++ b/MacOSX-Framework
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/Makefile.am b/Makefile.am
index 75d9ce110..5c4815b2b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -202,6 +202,7 @@ checksrc:
(cd tests && $(MAKE) checksrc)
(cd include/gnurl && $(MAKE) checksrc)
(cd docs/examples && $(MAKE) checksrc)
+ (cd packages && $(MAKE) checksrc)
tidy:
(cd src && $(MAKE) tidy)
diff --git a/Makefile.dist b/Makefile.dist
index a6316ab5f..69217a9eb 100644
--- a/Makefile.dist
+++ b/Makefile.dist
@@ -5,11 +5,11 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -28,18 +28,6 @@ ssl:
./configure --with-ssl
make
-watcom: .SYMBOLIC
- cd lib && $(MAKE) -u -f Makefile.Watcom
- cd src && $(MAKE) -u -f Makefile.Watcom
-
-watcom-clean: .SYMBOLIC
- cd lib && $(MAKE) -u -f Makefile.Watcom clean
- cd src && $(MAKE) -u -f Makefile.Watcom clean
-
-watcom-vclean: .SYMBOLIC
- cd lib && $(MAKE) -u -f Makefile.Watcom vclean
- cd src && $(MAKE) -u -f Makefile.Watcom vclean
-
mingw32:
$(MAKE) -C lib -f Makefile.m32
$(MAKE) -C src -f Makefile.m32
diff --git a/README b/README
index db9f6a10c..022e10e55 100644
--- a/README
+++ b/README
@@ -204,16 +204,14 @@ README
You find answers to the most frequent questions we get in the FAQ document.
- Study the COPYING file for distribution terms and similar. If you distribute
- curl binaries or other binaries that involve libcurl, you might enjoy the
- LICENSE-MIXING document.
+ Study the COPYING file for distribution terms.
- All of those documents and more can be found in the docs/ directory.
+ Those documents and more can be found in the docs/ directory.
CONTACT
If you have problems, questions, ideas or suggestions, please contact us
- by posting to a suitable mailing list. See https://curl.haxx.se/mail/
+ by posting to a suitable mailing list. See https://curl.se/mail/
All contributors to the project are listed in the THANKS document.
@@ -221,7 +219,7 @@ WEBSITE
Visit the curl website for the latest news and downloads:
- https://curl.haxx.se/
+ https://curl.se/
GIT
diff --git a/README.md b/README.md
index 363fd4929..1479aa36d 100644
--- a/README.md
+++ b/README.md
@@ -3,35 +3,35 @@ gnurl
[![Travis-CI Build Status](https://travis-ci.org/teknokatze/gnurl.svg?branch=master)](https://travis-ci.org/teknokatze/gnurl)
[![Cirrus Build Status](https://api.cirrus-ci.com/github/teknokatze/gnurl.svg?branch=master)](https://cirrus-ci.com/github/teknokatze/gnurl)
+![curl logo](https://curl.se/logo/curl-logo.svg)
Curl is a command-line tool for transferring data specified with URL
syntax. Find out how to use curl by reading [the curl.1 man
-page](https://curl.haxx.se/docs/manpage.html) or [the MANUAL
-document](https://curl.haxx.se/docs/manual.html). Find out how to install Curl
-by reading [the INSTALL document](https://curl.haxx.se/docs/install.html).
+page](https://curl.se/docs/manpage.html) or [the MANUAL
+document](https://curl.se/docs/manual.html). Find out how to install Curl
+by reading [the INSTALL document](https://curl.se/docs/install.html).
libcurl is the library curl is using to do its job. It is readily available to
be used by your software. Read [the libcurl.3 man
-page](https://curl.haxx.se/libcurl/c/libcurl.html) to learn how!
+page](https://curl.se/libcurl/c/libcurl.html) to learn how!
-You can find answers to the most frequent questions for curl in [the FAQ document](https://curl.haxx.se/docs/faq.html).
+You can find answers to the most frequent questions for curl in [the FAQ
+document](https://curl.se/docs/faq.html).
-Study [the COPYING file](https://curl.haxx.se/docs/copyright.html) for
-distribution terms and similar. If you distribute curl binaries or other
-binaries that involve libcurl, you might enjoy [the LICENSE-MIXING
-document](https://curl.haxx.se/legal/licmix.html).
+Study [the COPYING file](https://curl.se/docs/copyright.html) for
+distribution terms.
## Contact
-For curl, if you have problems, questions, ideas or suggestions, please contact us by posting to a suitable [mailing list](https://curl.haxx.se/mail/).
+For curl, if you have problems, questions, ideas or suggestions, please contact us by posting to a suitable [mailing list](https://curl.se/mail/).
For gnurl, if you have problems, questions, ideas or suggestions, please contact us by posting to a suitable [mailing list](https://gnunet.org/en/engage.html) or bug tracker.
-All curl contributors to the project are listed in [the THANKS document](https://curl.haxx.se/docs/thanks.html).
+All curl contributors to the project are listed in [the THANKS document](https://curl.se/docs/thanks.html).
## Website
Visit the [gnurl web site](https://gnunet.org/en/gnurl.html/) for the latest news and downloads.
-For curl specific information, visit the [curl web site](https://curl.haxx.se/).
+For curl specific information, visit the [curl web site](https://curl.se/).
## Git
@@ -44,7 +44,7 @@ To download the very latest source from the Git server do this:
## Security problems
gnurl is a fork of curl. Any security problems should first be tested with curl.
-In the unlikely case that you suspect a gnurl specific security problem, report it to the author of this software (ng0, gnunet.org).
+In the unlikely case that you suspect a gnurl specific security problem, report it to the author of this fork software (Nikita, gnunet).
## Notice
@@ -54,8 +54,7 @@ included here to comply with the distribution terms.
## Backers
-In the unlikely case anyone wants to sponsor my work, which primarily covers NetBSD and GNUnet now, [[click here](https://www.patreon.com/ng0)].
-The continued work on this (micro)fork of curl is financed for by [[Taler SA](https://taler.net)].
+In the unlikely case anyone wants to sponsor my work, which primarily covers NetBSD and GNUnet now, [[click here](https://www.patreon.com/teknokatze)].
## Curl - Please support the development of curl, section below from [curl/curl](https://github.com/curl/curl)
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index 363c7c947..a96762961 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -1,242 +1,248 @@
-curl and libcurl 7.72.0
+curl and libcurl 7.74.0
- Public curl releases: 194
- Command line options: 232
- curl_easy_setopt() options: 277
- Public functions in libcurl: 82
- Contributors: 2239
+ Public curl releases: 196
+ Command line options: 235
+ curl_easy_setopt() options: 284
+ Public functions in libcurl: 85
+ Contributors: 2287
This release includes the following changes:
- o content_encoding: add zstd decoding support [1]
- o CURL_PUSH_ERROROUT: allow the push callback to fail the parent stream [31]
- o CURLINFO_EFFECTIVE_METHOD: added [34]
+ o hsts: add experimental support for Strict-Transport-Security [37]
This release includes the following bugfixes:
- o CVE-2020-8231: libcurl: wrong connect-only connection [98]
- o appveyor: collect libcurl.dll variants with prefix or suffix [38]
- o asyn-ares: correct some bad comments [94]
- o bearssl: fix build with disabled proxy support [16]
- o buildconf: avoid array concatenation in die() [64]
- o buildconf: retire ares buildconf invocation
- o checksrc: ban gmtime/localtime [40]
- o checksrc: invoke script with -D to find .checksrc proper [63]
- o CI/azure: install libssh2 for use with msys2-based builds [67]
- o CI/azure: unconditionally enable warnings-as-errors with autotools [19]
- o CI/macos: enable warnings as errors for CMake builds [4]
- o CI/macos: set minimum macOS version [56]
- o CI/macos: unconditionally enable warnings-as-errors with autotools [21]
- o CI: Add muse CI analyzer [79]
- o cirrus-ci: upgrade 11-STABLE to 11.4 [2]
- o CMake: don't complain about missing nroff [87]
- o CMake: fix test for warning suppressions [17]
- o cmake: fix windows xp build [13]
- o configure.ac: Sort features name in summary [6]
- o configure: allow disabling warnings [26]
- o configure: cleanup wolfssl + pkg-config conflicts when cross compiling. [48]
- o configure: show zstd "no" in summary when built without it [49]
- o connect: remove redundant message about connect failure [66]
- o curl-config: ignore REQUIRE_LIB_DEPS in --libs output [96]
- o curl.1: add a few missing valid exit codes [76]
- o curl: add %{method} to the -w variables
- o curl: improve the existing file check with -J [43]
- o curl_multi_setopt: fix compiler warning "result is always false" [42]
- o curl_version_info.3: CURL_VERSION_KERBEROS4 is deprecated [9]
- o CURLINFO_CERTINFO.3: fix typo [3]
- o CURLOPT_NOBODY.3: clarify what setting to 0 means [46]
- o docs: add date of 7.20 to CURLM_CALL_MULTI_PERFORM mentions [18]
- o docs: Add video link to docs/CONTRIBUTE.md [95]
- o docs: change "web site" to "website" [86]
- o docs: clarify MAX_SEND/RECV_SPEED functionality [92]
- o docs: Update a few leftover mentions of DarwinSSL [29]
- o doh: remove redundant cast [20]
- o file2memory: use a define instead of -1 unsigned value [30]
- o ftp: don't do ssl_shutdown instead of ssl_close [85]
- o ftpserver: don't verify SMTP MAIL FROM names [8]
- o getinfo: reset retry-after value in initinfo [51]
- o gnutls: repair the build with `CURL_DISABLE_PROXY` [5]
- o gtls: survive not being able to get name/issuer [73]
- o h2: repair trailer handling [81]
- o http2: close the http2 connection when no more requests may be sent [7]
- o http2: fix nghttp2_strerror -> nghttp2_http2_strerror in debug messages [11]
- o libssh2: s/ssherr/sftperr/ [78]
- o libtest/Makefile.am: add -no-undefined for libstubgss for Cygwin [91]
- o md(4|5): don't use deprecated macOS functions [23]
- o mprintf: Fix dollar string handling [54]
- o mprintf: Fix stack overflows [53]
- o multi: Condition 'extrawait' is always true [60]
- o multi: Remove 10-year old out-commented code [97]
- o multi: remove two checks always true [36]
- o multi: update comment to say easyp list is linear [44]
- o multi_remove_handle: close unused connect-only connections [62]
- o ngtcp2: adapt to error code rename [69]
- o ngtcp2: adjust to recent sockaddr updates [27]
- o ngtcp2: update to modified qlog callback prototype [14]
- o nss: fix build with disabled proxy support [32]
- o ntlm: free target_info before (re-)malloc [55]
- o openssl: fix build with LibreSSL < 2.9.1 [61]
- o page-header: provide protocol details in the curl.1 man page [28]
- o quiche: handle calling disconnect twice [50]
- o runtests.pl: treat LibreSSL and BoringSSL as OpenSSL [59]
- o runtests: move the gnutls-serv tests to a dynamic port [74]
- o runtests: move the smbserver to use a dynamic port number [71]
- o runtests: move the TELNET server to a dynamic port [68]
- o runtests: run the DICT server on a random port number [90]
- o runtests: run the http2 tests on a random port number [72]
- o runtests: support dynamicly base64 encoded sections in tests [75]
- o setopt: unset NOBODY switches to GET if still HEAD [47]
- o smtp_parse_address: handle blank input string properly [89]
- o socks: use size_t for size variable [39]
- o strdup: remove the odd strlen check [24]
- o test1119: verify stdout in the test [33]
- o test1139: make it display the difference on test failures
- o test1140: compare stdout [93]
- o test1908: treat file as text [83]
- o tests/FILEFORMAT.md: mention %HTTP2PORT
- o tests/sshserver.pl: fix compatibility with OpenSSH for Windows
- o TLS naming: fix more Winssl and Darwinssl leftovers [88]
- o tls-max.d: this option is only for TLS-using connections [45]
- o tlsv1.3.d. only for TLS-using connections [37]
- o tool_doswin: Simplify Windows version detection [57]
- o tool_getparam: make --krb option work again [10]
- o TrackMemory tests: ignore realloc and free in getenv.c [84]
- o transfer: fix data_pending for builds with both h2 and h3 enabled [41]
- o transfer: fix memory-leak with CURLOPT_CURLU in a duped handle [15]
- o transfer: move retrycount from connect struct to easy handle [77]
- o travis/script.sh: fix use of `-n' with unquoted envvar [80]
- o travis: add ppc64le and s390x builds [65]
- o travis: update quiche builds for new boringssl layout [25]
- o url: fix CURLU and location following [70]
- o url: silence MSVC warning [12]
- o util: silence conversion warnings [22]
- o win32: Add Curl_verify_windows_version() to curlx [58]
- o WIN32: stop forcing narrow-character API [52]
- o windows: add unicode to feature list [35]
- o windows: disable Unix Sockets for old mingw [82]
+ o CVE-2020-8286: Inferior OCSP verification [93]
+ o CVE-2020-8285: FTP wildcard stack overflow [95]
+ o CVE-2020-8284: trusting FTP PASV responses [97]
+ o acinclude: detect manually set minimum macos/ipod version [46]
+ o alt-svc: enable (in the build) by default [20]
+ o alt-svc: minimize variable scope and avoid "DEAD_STORE" [51]
+ o asyn: use 'struct thread_data *' instead of 'void *' [84]
+ o checksrc: warn on empty line before open brace [13]
+ o CI/appveyor: disable test 571 in two cmake builds [22]
+ o CI/azure: improve on flakiness by avoiding libtool wrappers [7]
+ o CI/tests: enable test target on TravisCI for CMake builds [38]
+ o CI/travis: add brotli and zstd to the libssh2 build [27]
+ o cirrus: build with FreeBSD 12.2 in CirrusCI [80]
+ o cmake: call the feature unixsockets without dash [26]
+ o cmake: check for linux/tcp.h [91]
+ o cmake: correctly handle linker flags for static libs [52]
+ o cmake: don't pass -fvisibility=hidden to clang-cl on Windows [53]
+ o cmake: don't use reserved target name 'test' [79]
+ o cmake: make BUILD_TESTING dependent option [30]
+ o cmake: make CURL_ZLIB a tri-state variable [70]
+ o cmake: set the unicode feature in curl-config on Windows [23]
+ o cmake: store IDN2 information in curl_config.h [25]
+ o cmake: use libcurl.rc in all Windows builds [69]
+ o configure: pass -pthread to Libs.private for pkg-config [50]
+ o configure: use pkgconfig to find openSSL when cross-compiling [28]
+ o connect: repair build without ipv6 availability [19]
+ o curl.1: add an "OUTPUT" section at the top of the manpage [32]
+ o curl.se: new home [59]
+ o curl: add compatibility for Amiga and GCC 6.5 [61]
+ o curl: only warn not fail, if not finding the home dir [15]
+ o curl_easy_escape: limit output string length to 3 * max input [55]
+ o Curl_pgrsStartNow: init speed limit time stamps at start [48]
+ o curl_setup: USE_RESOLVE_ON_IPS is for Apple native resolver use
+ o curl_url_set.3: fix typo in the RETURN VALUE section [3]
+ o CURLOPT_DNS_USE_GLOBAL_CACHE.3: fix typo [34]
+ o CURLOPT_HSTS.3: document the file format [82]
+ o CURLOPT_NOBODY.3: fix typo [6]
+ o CURLOPT_TCP_NODELAY.3: fix comment in example code [8]
+ o CURLOPT_URL.3: clarify SCP/SFTP URLs are for uploads as well
+ o docs: document the 8MB input string limit [57]
+ o docs: fix typos and markup in ETag manpage sections [87]
+ o docs: Fix various typos in documentation [58]
+ o examples/httpput: remove use of CURLOPT_PUT [39]
+ o FAQ: refreshed [56]
+ o file: avoid duplicated code sequence [77]
+ o ftp: retry getpeername for FTP with TCP_FASTOPEN [100]
+ o gnutls: fix memory leaks (certfields memory wasn't released) [41]
+ o header.d: mention the "Transfer-Encoding: chunked" handling [45]
+ o HISTORY: the new domain
+ o http3: fix two build errors, silence warnings [10]
+ o http3: use the master branch of GnuTLS for testing [88]
+ o http: pass correct header size to debug callback for chunked post [44]
+ o http_proxy: use enum with state names for 'keepon' [54]
+ o httpput-postfields.c: new example doing PUT with POSTFIELDS [35]
+ o infof/failf calls: fix format specifiers [78]
+ o libssh2: fix build with disabled proxy support [17]
+ o libssh2: fix transport over HTTPS proxy [31]
+ o libssh2: require version 1.0 or later [24]
+ o Makefile.m32: add support for HTTP/3 via ngtcp2+nghttp3 [11]
+ o Makefile.m32: add support for UNICODE builds [85]
+ o mqttd: fclose test file when done [60]
+ o NEW-PROTOCOL: document what needs to be done to add one [92]
+ o ngtcp2: adapt to recent nghttp3 updates [49]
+ o ngtcp2: advertise h3 ALPN unconditionally [72]
+ o ngtcp2: Fix build error due to symbol name change [90]
+ o ngtcp2: use the minimal version of QUIC supported by ngtcp2 [67]
+ o ntlm: avoid malloc(0) on zero length user and domain [96]
+ o openssl: acknowledge SRP disabling in configure properly [9]
+ o openssl: free mem_buf in error path [94]
+ o openssl: guard against OOM on context creation [68]
+ o openssl: use OPENSSL_init_ssl() with >= 1.1.0 [66]
+ o os400: Sync libcurl API options [5]
+ o packages/OS400: make the source code-style compliant [4]
+ o quiche: close the connection [89]
+ o quiche: remove 'static' from local buffer [71]
+ o range.d: clarify that curl will not parse multipart responses [36]
+ o range.d: fix typo
+ o Revert "multi: implement wait using winsock events" [99]
+ o rtsp: error out on empty Session ID, unified the code
+ o rtsp: fixed Session ID comparison to refuse prefix [65]
+ o rtsp: fixed the RTST Session ID mismatch in test 570 [64]
+ o runtests: return error if no tests ran [16]
+ o runtests: revert the mistaken edit of $CURL
+ o runtests: show keywords when no tests ran [33]
+ o scripts/completion.pl: parse all opts [101]
+ o socks: check for DNS entries with the right port number [74]
+ o src/tool_filetime: disable -Wformat on mingw for this file [2]
+ o strerror: use 'const' as the string should never be modified [18]
+ o test122[12]: remove these two tests [1]
+ o test506: make it not run in c-ares builds [75]
+ o tests/*server.py: close log file after each log line [81]
+ o tests/server/tftpd.c: close upload file right after transfer [62]
+ o tests/util.py: fix compatibility with Python 2 [83]
+ o tests: add missing global_init/cleanup calls [42]
+ o tests: fix some http/2 tests for older versions of nghttpx [47]
+ o tool_debug_cb: do not assume zero-terminated data
+ o tool_help: make "output" description less confusing [21]
+ o tool_operate: --retry for HTTP 408 responses too [43]
+ o tool_operate: bail out proper on errors during parallel transfers [29]
+ o tool_operate: fix compiler warning when --libcurl is disabled [12]
+ o tool_writeout: use off_t getinfo-types instead of doubles [76]
+ o travis: use ninja-build for CMake builds [63]
+ o travis: use valgrind when running tests for debug builds [40]
+ o urlapi: don't accept blank port number field without scheme [98]
+ o urlapi: URL encode a '+' in the query part [14]
+ o urldata: remove 'void *protop' and create the union 'p' [86]
+ o vquic/ngtcp2.h: define local_addr as sockaddr_storage [73]
This release includes the following known bugs:
- o see docs/KNOWN_BUGS (https://curl.haxx.se/docs/knownbugs.html)
+ o see docs/KNOWN_BUGS (https://curl.se/docs/knownbugs.html)
This release would not have looked like this without help, code, reports and
advice from friends like these:
- Alessandro Ghedini, Alex Kiernan, Baruch Siach, Bevan Weiss, Brian Inglis,
- BrumBrum on hackerone, Cameron Cawley, Carlo Marcelo Arenas Belón,
- causal-agent on github, Cherish98 on github, Dan Fandrich, Daniel Gustafsson,
- Daniel Stenberg, Denis Goleshchikhin, divinity76 on github, Ehren Bendler,
- Emil Engler, Erik Johansson, Filip Salomonsson, Gilles Vollant, Gisle Vanem,
- H3RSKO on github, ihsinme on github, Jeremy Maitin-Shepard,
- joey-l-us on github, Jonathan Cardoso Machado, Jonathan Nieder, Kamil Dudka,
- Ken Brown, Laramie Leavitt, lilongyan-huawei on github, Marc Aldorasi,
- Marcel Raad, Marc Hörsken, Masaya Suzuki, Matthias Naegler,
- Nicolas Sterchele, NobodyXu on github, Peter Wu, ramsay-jones on github,
- Rasmus Melchior Jacobsen, Ray Satiro, sspiri on github, Stefan Yohansson,
- Tadej Vengust, Tatsuhiro Tsujikawa, tbugfinder on github,
- Thomas M. DuBuisson, Tobias Stoeckmann, Tomas Berger, Viktor Szakats,
- xwxbug on github,
- (52 contributors)
+ Andreas Fischer, asavah on github, b9a1 on github, Baruch Siach,
+ Basuke Suzuki, bobmitchell1956 on github, BrumBrum on hackerone,
+ Cristian Morales Vega, d4d on hackerone, Daiki Ueno, Daniel Gustafsson,
+ Daniel Stenberg, Dietmar Hauser, Dirk Wetter, emanruse on github,
+ Emil Engler, hamstergene on github, Harry Sintonen, Jacob Hoffman-Andrews,
+ Jakub Zakrzewski, Jeroen Ooms, Jon Rumsey, José Joaquín Atria, Junho Choi,
+ Kael1117 on github, Klaus Crusius, Kovalkov Dmitrii, Marcel Raad,
+ Marc Hörsken, Marc Schlatter, Niranjan Hasabnis, nosajsnikta on github,
+ Oliver Urbann, Per Nilsson, Philipp Klaus Krause, Ray Satiro,
+ Rikard Falkeborn, Rui LIU, Sergei Nikulov, Thomas Danielsson, Tobias Hieta,
+ Tom G. Christensen, Varnavas Papaioannou, Viktor Szakats, Vincent Torri,
+ xnynx on github,
+ (46 contributors)
Thanks! (and sorry if I forgot to mention someone)
References to bug reports and discussions on issues:
- [1] = https://curl.haxx.se/bug/?i=5453
- [2] = https://curl.haxx.se/bug/?i=5668
- [3] = https://curl.haxx.se/bug/?i=5655
- [4] = https://curl.haxx.se/bug/?i=5716
- [5] = https://curl.haxx.se/bug/?i=5645
- [6] = https://curl.haxx.se/bug/?i=5656
- [7] = https://curl.haxx.se/bug/?i=5643
- [8] = https://curl.haxx.se/bug/?i=5639
- [9] = https://curl.haxx.se/bug/?i=5642
- [10] = https://bugzilla.redhat.com/1833193
- [11] = https://curl.haxx.se/bug/?i=5641
- [12] = https://curl.haxx.se/bug/?i=5638
- [13] = https://curl.haxx.se/bug/?i=5662
- [14] = https://curl.haxx.se/bug/?i=5675
- [15] = https://curl.haxx.se/bug/?i=5665
- [16] = https://curl.haxx.se/bug/?i=5666
- [17] = https://curl.haxx.se/bug/?i=5714
- [18] = https://curl.haxx.se/bug/?i=5744
- [19] = https://curl.haxx.se/bug/?i=5706
- [20] = https://curl.haxx.se/bug/?i=5704
- [21] = https://curl.haxx.se/bug/?i=5694
- [22] = https://curl.haxx.se/bug/?i=5695
- [23] = https://curl.haxx.se/bug/?i=5695
- [24] = https://curl.haxx.se/bug/?i=5697
- [25] = https://curl.haxx.se/bug/?i=5691
- [26] = https://curl.haxx.se/bug/?i=5689
- [27] = https://curl.haxx.se/bug/?i=5690
- [28] = https://curl.haxx.se/bug/?i=5679
- [29] = https://curl.haxx.se/bug/?i=5688
- [30] = https://curl.haxx.se/bug/?i=5683
- [31] = https://curl.haxx.se/bug/?i=5636
- [32] = https://curl.haxx.se/bug/?i=5667
- [33] = https://curl.haxx.se/bug/?i=5644
- [34] = https://curl.haxx.se/bug/?i=5511
- [35] = https://curl.haxx.se/bug/?i=5491
- [36] = https://curl.haxx.se/bug/?i=5676
- [37] = https://curl.haxx.se/bug/?i=5764
- [38] = https://curl.haxx.se/bug/?i=5659
- [39] = https://curl.haxx.se/bug/?i=5654
- [40] = https://curl.haxx.se/bug/?i=5732
- [41] = https://curl.haxx.se/bug/?i=5734
- [42] = https://github.com/curl/curl/commit/61a08508f6a458fe21bbb18cd2a9bac2f039452b#commitcomment-40941232
- [43] = https://hackerone.com/reports/926638
- [44] = https://curl.haxx.se/bug/?i=5737
- [45] = https://curl.haxx.se/bug/?i=5764
- [46] = https://curl.haxx.se/bug/?i=5729
- [47] = https://curl.haxx.se/bug/?i=5725
- [48] = https://curl.haxx.se/bug/?i=5605
- [49] = https://curl.haxx.se/bug/?i=5720
- [50] = https://curl.haxx.se/bug/?i=5726
- [51] = https://curl.haxx.se/bug/?i=5661
- [52] = https://curl.haxx.se/bug/?i=5658
- [53] = https://curl.haxx.se/bug/?i=5722
- [54] = https://curl.haxx.se/bug/?i=5722
- [55] = https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=24379
- [56] = https://curl.haxx.se/bug/?i=5723
- [57] = https://curl.haxx.se/bug/?i=5754
- [58] = https://curl.haxx.se/bug/?i=5754
- [59] = https://curl.haxx.se/bug/?i=5762
- [60] = https://curl.haxx.se/bug/?i=5759
- [61] = https://curl.haxx.se/bug/?i=5757
- [62] = https://curl.haxx.se/bug/?i=5749
- [63] = https://curl.haxx.se/bug/?i=5715
- [64] = https://curl.haxx.se/bug/?i=5701
- [65] = https://curl.haxx.se/bug/?i=5752
- [66] = https://curl.haxx.se/bug/?i=5708
- [67] = https://curl.haxx.se/bug/?i=5721
- [68] = https://curl.haxx.se/bug/?i=5785
- [69] = https://curl.haxx.se/bug/?i=5786
- [70] = https://curl.haxx.se/bug/?i=5709
- [71] = https://curl.haxx.se/bug/?i=5782
- [72] = https://curl.haxx.se/bug/?i=5779
- [73] = https://curl.haxx.se/bug/?i=5778
- [74] = https://curl.haxx.se/bug/?i=5778
- [75] = https://curl.haxx.se/bug/?i=5761
- [76] = https://curl.haxx.se/bug/?i=5777
- [77] = https://curl.haxx.se/bug/?i=5794
- [78] = https://github.com/curl/curl/commit/7370b4e39f1390e701f5b68d910c619151daf72b#r41334700
- [79] = https://curl.haxx.se/bug/?i=5772
- [80] = https://curl.haxx.se/bug/?i=5773
- [81] = https://curl.haxx.se/bug/?i=5663
- [82] = https://curl.haxx.se/bug/?i=5674
- [83] = https://curl.haxx.se/bug/?i=5767
- [84] = https://curl.haxx.se/bug/?i=5767
- [85] = https://curl.haxx.se/bug/?i=5797
- [86] = https://curl.haxx.se/bug/?i=5822
- [87] = https://curl.haxx.se/bug/?i=5817
- [88] = https://curl.haxx.se/bug/?i=5795
- [89] = https://curl.haxx.se/bug/?i=5792
- [90] = https://curl.haxx.se/bug/?i=5783
- [91] = https://curl.haxx.se/bug/?i=5819
- [92] = https://curl.haxx.se/bug/?i=5788
- [93] = https://curl.haxx.se/bug/?i=5814
- [94] = https://curl.haxx.se/bug/?i=5812
- [95] = https://curl.haxx.se/bug/?i=5811
- [96] = https://curl.haxx.se/bug/?i=5793
- [97] = https://curl.haxx.se/bug/?i=5805
- [98] = https://curl.haxx.se/docs/CVE-2020-8231.html
+ [1] = https://curl.se/bug/?i=6080
+ [2] = https://curl.se/bug/?i=6079
+ [3] = https://curl.se/bug/?i=6102
+ [4] = https://curl.se/bug/?i=6085
+ [5] = https://curl.se/bug/?i=6083
+ [6] = https://curl.se/bug/?i=6097
+ [7] = https://curl.se/bug/?i=6049
+ [8] = https://curl.se/bug/?i=6096
+ [9] = https://curl.se/mail/lib-2020-10/0037.html
+ [10] = https://curl.se/bug/?i=6093
+ [11] = https://curl.se/bug/?i=6092
+ [12] = https://curl.se/bug/?i=6095
+ [13] = https://curl.se/bug/?i=6088
+ [14] = https://curl.se/bug/?i=6086
+ [15] = https://curl.se/bug/?i=6200
+ [16] = https://curl.se/bug/?i=6053
+ [17] = https://curl.se/bug/?i=6125
+ [18] = https://curl.se/bug/?i=6068
+ [19] = https://curl.se/bug/?i=6069
+ [20] = https://curl.se/bug/?i=5868
+ [21] = https://curl.se/bug/?i=6118
+ [22] = https://curl.se/bug/?i=6119
+ [23] = https://curl.se/bug/?i=6117
+ [24] = https://curl.se/bug/?i=6116
+ [25] = https://curl.se/bug/?i=6108
+ [26] = https://curl.se/bug/?i=6108
+ [27] = https://curl.se/bug/?i=6105
+ [28] = https://curl.se/bug/?i=6145
+ [29] = https://curl.se/bug/?i=6141
+ [30] = https://curl.se/bug/?i=6072
+ [31] = https://curl.se/bug/?i=6113
+ [32] = https://curl.se/bug/?i=6134
+ [33] = https://curl.se/bug/?i=6126
+ [34] = https://curl.se/bug/?i=6131
+ [35] = https://curl.se/bug/?i=6188
+ [36] = https://curl.se/bug/?i=6124
+ [37] = https://curl.se/bug/?i=5896
+ [38] = https://curl.se/bug/?i=6074
+ [39] = https://curl.se/bug/?i=6186
+ [40] = https://curl.se/bug/?i=6154
+ [41] = https://curl.se/bug/?i=6153
+ [42] = https://curl.se/bug/?i=6156
+ [43] = https://curl.se/bug/?i=6155
+ [44] = https://curl.se/bug/?i=6147
+ [45] = https://curl.se/bug/?i=6148
+ [46] = https://curl.se/bug/?i=6138
+ [47] = https://curl.se/bug/?i=6139
+ [48] = https://curl.se/bug/?i=6162
+ [49] = https://curl.se/bug/?i=6185
+ [50] = https://curl.se/bug/?i=6168
+ [51] = https://curl.se/bug/?i=6182
+ [52] = https://curl.se/bug/?i=6195
+ [53] = https://curl.se/bug/?i=6194
+ [54] = https://curl.se/mail/lib-2020-11/0026.html
+ [55] = https://curl.se/bug/?i=6192
+ [56] = https://curl.se/bug/?i=6177
+ [57] = https://curl.se/bug/?i=6190
+ [58] = https://curl.se/bug/?i=6171
+ [59] = https://curl.se/bug/?i=6172
+ [60] = https://curl.se/bug/?i=6058
+ [61] = https://curl.se/bug/?i=6220
+ [62] = https://curl.se/bug/?i=6058
+ [63] = https://curl.se/bug/?i=6077
+ [64] = https://curl.se/bug/?i=6161
+ [65] = https://curl.se/bug/?i=6161
+ [66] = https://curl.se/bug/?i=6254
+ [67] = https://curl.se/bug/?i=6250
+ [68] = https://curl.se/bug/?i=6224
+ [69] = https://curl.se/bug/?i=6215
+ [70] = https://curl.se/bug/?i=6173
+ [71] = https://curl.se/bug/?i=6223
+ [72] = https://curl.se/bug/?i=6250
+ [73] = https://curl.se/bug/?i=6250
+ [74] = https://curl.se/bug/?i=6247
+ [75] = https://curl.se/bug/?i=6247
+ [76] = https://curl.se/bug/?i=6248
+ [77] = https://curl.se/bug/?i=6249
+ [78] = https://curl.se/bug/?i=6241
+ [79] = https://curl.se/bug/?i=6257
+ [80] = https://curl.se/bug/?i=6211
+ [81] = https://curl.se/bug/?i=6058
+ [82] = https://curl.se/bug/?i=6205
+ [83] = https://curl.se/bug/?i=6259
+ [84] = https://curl.se/bug/?i=6239
+ [85] = https://curl.se/bug/?i=6228
+ [86] = https://curl.se/bug/?i=6238
+ [87] = https://curl.se/bug/?i=6273
+ [88] = https://curl.se/bug/?i=6235
+ [89] = https://curl.se/bug/?i=6213
+ [90] = https://curl.se/bug/?i=6271
+ [91] = https://curl.se/bug/?i=6252
+ [92] = https://curl.se/bug/?i=6263
+ [93] = https://curl.se/docs/CVE-2020-8286.html
+ [94] = https://curl.se/bug/?i=6267
+ [95] = https://curl.se/docs/CVE-2020-8285.html
+ [96] = https://curl.se/bug/?i=6264
+ [97] = https://curl.se/docs/CVE-2020-8284.html
+ [98] = https://curl.se/bug/?i=6283
+ [99] = https://curl.se/bug/?i=6146
+ [100] = https://curl.se/bug/?i=6252
+ [101] = https://curl.se/bug/?i=6280
diff --git a/acinclude.m4 b/acinclude.m4
index 089449bac..61ecd4fe1 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -661,7 +661,7 @@ dnl -------------------------------------------------
dnl Check for libraries needed for WINLDAP support,
dnl and prepended to LIBS any needed libraries.
dnl This macro can take an optional parameter with a
-dnl white space separated list of libraries to check
+dnl whitespace separated list of libraries to check
dnl before the WINLDAP default ones.
AC_DEFUN([CURL_CHECK_LIBS_WINLDAP], [
@@ -755,7 +755,7 @@ dnl -------------------------------------------------
dnl Check for libraries needed for LDAP support,
dnl and prepended to LIBS any needed libraries.
dnl This macro can take an optional parameter with a
-dnl white space separated list of libraries to check
+dnl whitespace separated list of libraries to check
dnl before the default ones.
AC_DEFUN([CURL_CHECK_LIBS_LDAP], [
@@ -1880,11 +1880,6 @@ AC_DEFUN([CURL_CHECK_FUNC_SELECT], [
#endif
#endif
#ifndef HAVE_WINDOWS_H
-#ifdef HAVE_PROTO_BSDSOCKET_H
-#include <proto/bsdsocket.h>
-struct Library *SocketBase = NULL;
-#define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0)
-#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#elif defined(HAVE_UNISTD_H)
@@ -1893,6 +1888,11 @@ struct Library *SocketBase = NULL;
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
+#ifdef HAVE_PROTO_BSDSOCKET_H
+#include <proto/bsdsocket.h>
+struct Library *SocketBase = NULL;
+#define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0)
+#endif
#endif
]],[[
select(0, 0, 0, 0, 0);
@@ -1945,11 +1945,6 @@ struct Library *SocketBase = NULL;
#endif
#endif
#ifndef HAVE_WINDOWS_H
-#ifdef HAVE_PROTO_BSDSOCKET_H
-#include <proto/bsdsocket.h>
-struct Library *SocketBase = NULL;
-#define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0)
-#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#elif defined(HAVE_UNISTD_H)
@@ -1958,6 +1953,11 @@ struct Library *SocketBase = NULL;
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
+#ifdef HAVE_PROTO_BSDSOCKET_H
+#include <proto/bsdsocket.h>
+struct Library *SocketBase = NULL;
+#define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0)
+#endif
#define SELECTCALLCONV
#endif
#ifndef HAVE_STRUCT_TIMEVAL
@@ -2526,14 +2526,20 @@ AC_DEFUN([CURL_MAC_CFLAGS], [
AC_MSG_RESULT([$tst_cflags]);
if test "$tst_cflags" = "yes"; then
- AC_MSG_CHECKING([for *version-min in CFLAGS])
+ AC_MSG_CHECKING([for *version-min set by user])
min=""
- if test -z "$(echo $CFLAGS | grep m.*os.*-version-min)"; then
+ if test -n "$IPHONEOS_DEPLOYMENT_TARGET"; then
+ var="IPHONEOS_DEPLOYMENT_TARGET"
+ elif test -n "$MACOSX_DEPLOYMENT_TARGET"; then
+ var="MACOSX_DEPLOYMENT_TARGET"
+ elif test -z "$(echo $CFLAGS $CC | grep m.*os.*-version-min)"; then
min="-mmacosx-version-min=10.8"
CFLAGS="$CFLAGS $min"
+ else
+ var="CFLAGS or CC"
fi
if test -z "$min"; then
- AC_MSG_RESULT([set by user])
+ AC_MSG_RESULT([set by user in $var])
else
AC_MSG_RESULT([$min set])
fi
diff --git a/appveyor.yml b/appveyor.yml
index e34784159..dee5218bc 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -31,6 +31,7 @@ environment:
PRJ_CFG: Release
OPENSSL: OFF
SCHANNEL: ON
+ ENABLE_UNICODE: OFF
HTTP_ONLY: OFF
TESTING: OFF
SHARED: ON
@@ -43,6 +44,7 @@ environment:
PRJ_CFG: Release
OPENSSL: ON
SCHANNEL: OFF
+ ENABLE_UNICODE: OFF
HTTP_ONLY: OFF
TESTING: OFF
SHARED: ON
@@ -55,6 +57,7 @@ environment:
PRJ_CFG: Release
OPENSSL: OFF
SCHANNEL: ON
+ ENABLE_UNICODE: OFF
HTTP_ONLY: OFF
TESTING: OFF
SHARED: OFF
@@ -67,6 +70,7 @@ environment:
PRJ_CFG: Debug
OPENSSL: OFF
SCHANNEL: OFF
+ ENABLE_UNICODE: OFF
HTTP_ONLY: OFF
TESTING: ON
SHARED: OFF
@@ -79,10 +83,11 @@ environment:
PRJ_CFG: Debug
OPENSSL: OFF
SCHANNEL: ON
+ ENABLE_UNICODE: ON
HTTP_ONLY: OFF
TESTING: ON
SHARED: OFF
- DISABLED_TESTS: "!1139 !1501"
+ DISABLED_TESTS: "~571 !1139 !1501 "
COMPILER_PATH: ""
- APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2019"
BUILD_SYSTEM: CMake
@@ -91,10 +96,11 @@ environment:
PRJ_CFG: Debug
OPENSSL: OFF
SCHANNEL: OFF
+ ENABLE_UNICODE: OFF
HTTP_ONLY: OFF
TESTING: ON
SHARED: OFF
- DISABLED_TESTS: "!1139 !1501"
+ DISABLED_TESTS: "~571 !1139 !1501"
COMPILER_PATH: ""
- APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2019"
BUILD_SYSTEM: CMake
@@ -103,6 +109,7 @@ environment:
PRJ_CFG: Debug
OPENSSL: OFF
SCHANNEL: OFF
+ ENABLE_UNICODE: OFF
HTTP_ONLY: ON
TESTING: ON
SHARED: OFF
@@ -115,6 +122,7 @@ environment:
PRJ_CFG: Debug
OPENSSL: OFF
SCHANNEL: ON
+ ENABLE_UNICODE: ON
HTTP_ONLY: OFF
TESTING: ON
SHARED: OFF
@@ -128,6 +136,7 @@ environment:
PRJ_CFG: Debug
OPENSSL: OFF
SCHANNEL: ON
+ ENABLE_UNICODE: ON
HTTP_ONLY: OFF
TESTING: ON
SHARED: OFF
@@ -141,6 +150,7 @@ environment:
PRJ_CFG: Debug
OPENSSL: OFF
SCHANNEL: ON
+ ENABLE_UNICODE: OFF
HTTP_ONLY: OFF
TESTING: ON
SHARED: OFF
@@ -154,6 +164,7 @@ environment:
PRJ_CFG: Debug
OPENSSL: OFF
SCHANNEL: OFF
+ ENABLE_UNICODE: OFF
HTTP_ONLY: OFF
TESTING: ON
SHARED: OFF
@@ -221,12 +232,12 @@ environment:
BUILD_SYSTEM: autotools
TESTING: ON
DISABLED_TESTS: "!19 ~1056 !1233"
- CONFIG_ARGS: "--enable-debug --enable-werror --enable-alt-svc --disable-threaded-resolver --disable-proxy"
+ CONFIG_ARGS: "--enable-debug --enable-werror --disable-threaded-resolver --disable-proxy"
- APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2019"
BUILD_SYSTEM: autotools
TESTING: ON
DISABLED_TESTS: "!19 !504 !704 !705 ~1056 !1233"
- CONFIG_ARGS: "--enable-debug --enable-werror --enable-alt-svc --disable-threaded-resolver"
+ CONFIG_ARGS: "--enable-debug --enable-werror --disable-threaded-resolver"
- APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2019"
BUILD_SYSTEM: autotools
TESTING: ON
@@ -250,6 +261,7 @@ build_script:
-DBUILD_TESTING=%TESTING%
-DCURL_WERROR=ON
-DENABLE_DEBUG=ON
+ -DENABLE_UNICODE=%ENABLE_UNICODE%
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE=""
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG=""
-DCMAKE_INSTALL_PREFIX="C:/CURL"
@@ -279,11 +291,19 @@ build_script:
if %BUILD_SYSTEM%==autotools (
bash.exe -e -l -c "cd /c/projects/curl && ./buildconf && ./configure %CONFIG_ARGS% && make && make examples && cd tests && make"
)))))
+ - if %TESTING%==ON (
+ if %BUILD_SYSTEM%==CMake (
+ cmake --build . --config %PRJ_CFG% --parallel 2 --target testdeps
+ ))
test_script:
- if %TESTING%==ON (
- echo APPVEYOR_API_URL=%APPVEYOR_API_URL% &&
- bash.exe -e -l -c "cd /c/projects/curl/tests && ./runtests.pl -a -b$(($(echo '%APPVEYOR_API_URL%' | cut -d'/' -f3 | cut -d':' -f2)+1)) -p !flaky %DISABLED_TESTS%" )
+ if %BUILD_SYSTEM%==CMake (
+ set TFLAGS=%DISABLED_TESTS% &&
+ cmake --build . --config %PRJ_CFG% --target test-nonflaky
+ ) else (
+ echo APPVEYOR_API_URL=%APPVEYOR_API_URL% &&
+ bash.exe -e -l -c "cd /c/projects/curl/tests && ./runtests.pl -a -p !flaky %DISABLED_TESTS%" ))
# select branches to avoid testing feature branches twice (as branch and as pull request)
branches:
diff --git a/buildconf b/buildconf
index cb9a21bb9..4e4c17e99 100755
--- a/buildconf
+++ b/buildconf
@@ -1,432 +1,4 @@
#!/bin/sh
-#***************************************************************************
-# _ _ ____ _
-# Project ___| | | | _ \| |
-# / __| | | | |_) | |
-# | (__| |_| | _ <| |___
-# \___|\___/|_| \_\_____|
-#
-# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
-#
-# This software is licensed as described in the file COPYING, which
-# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
-#
-# You may opt to use, copy, modify, merge, publish, distribute and/or sell
-# copies of the Software, and permit persons to whom the Software is
-# furnished to do so, under the terms of the COPYING file.
-#
-# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
-# KIND, either express or implied.
-#
-###########################################################################
-#--------------------------------------------------------------------------
-# die prints argument string to stdout and exits this shell script.
-#
-die(){
- echo "buildconf: $*"
- exit 1
-}
-
-#--------------------------------------------------------------------------
-# findtool works as 'which' but we use a different name to make it more
-# obvious we aren't using 'which'! ;-)
-# Unlike 'which' does, the current directory is ignored.
-#
-findtool(){
- file="$1"
-
- if { echo "$file" | grep "/" >/dev/null 2>&1; } then
- # when file is given with a path check it first
- if test -f "$file"; then
- echo "$file"
- return
- fi
- fi
-
- old_IFS=$IFS; IFS=':'
- for path in $PATH
- do
- IFS=$old_IFS
- # echo "checks for $file in $path" >&2
- if test "$path" -a "$path" != '.' -a -f "$path/$file"; then
- echo "$path/$file"
- return
- fi
- done
- IFS=$old_IFS
-}
-
-#--------------------------------------------------------------------------
-# removethis() removes all files and subdirectories with the given name,
-# inside and below the current subdirectory at invocation time.
-#
-removethis(){
- if test "$#" = "1"; then
- find . -depth -name $1 -exec rm -rf {} \;
- fi
-}
-
-#--------------------------------------------------------------------------
-# Ensure that buildconf runs from the subdirectory where configure.ac lives
-#
-if test ! -f configure.ac ||
- test ! -f src/tool_main.c ||
- test ! -f lib/urldata.h ||
- test ! -f include/gnurl/curl.h ||
- test ! -f m4/curl-functions.m4; then
- echo "Can not run buildconf from outside of curl's source subdirectory!"
- echo "Change to the subdirectory where buildconf is found, and try again."
- exit 1
-fi
-
-#--------------------------------------------------------------------------
-# autoconf 2.57 or newer. Unpatched version 2.67 does not generate proper
-# configure script. Unpatched version 2.68 is simply unusable, we should
-# disallow 2.68 usage.
-#
-need_autoconf="2.57"
-ac_version=`${AUTOCONF:-autoconf} --version 2>/dev/null|head -n 1| sed -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'`
-if test -z "$ac_version"; then
- echo "buildconf: autoconf not found."
- echo " You need autoconf version $need_autoconf or newer installed."
- exit 1
-fi
-old_IFS=$IFS; IFS='.'; set $ac_version; IFS=$old_IFS
-if test "$1" = "2" -a "$2" -lt "57" || test "$1" -lt "2"; then
- echo "buildconf: autoconf version $ac_version found."
- echo " You need autoconf version $need_autoconf or newer installed."
- echo " If you have a sufficient autoconf installed, but it"
- echo " is not named 'autoconf', then try setting the"
- echo " AUTOCONF environment variable."
- exit 1
-fi
-
-if test "$1" = "2" -a "$2" -eq "67"; then
- echo "buildconf: autoconf version $ac_version (BAD)"
- echo " Unpatched version generates broken configure script."
-elif test "$1" = "2" -a "$2" -eq "68"; then
- echo "buildconf: autoconf version $ac_version (BAD)"
- echo " Unpatched version generates unusable configure script."
-else
- echo "buildconf: autoconf version $ac_version (ok)"
-fi
-
-am4te_version=`${AUTOM4TE:-autom4te} --version 2>/dev/null|head -n 1| sed -e 's/autom4te\(.*\)/\1/' -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'`
-if test -z "$am4te_version"; then
- echo "buildconf: autom4te not found. Weird autoconf installation!"
- exit 1
-fi
-if test "$am4te_version" = "$ac_version"; then
- echo "buildconf: autom4te version $am4te_version (ok)"
-else
- echo "buildconf: autom4te version $am4te_version (ERROR: does not match autoconf version)"
- exit 1
-fi
-
-#--------------------------------------------------------------------------
-# autoheader 2.50 or newer
-#
-ah_version=`${AUTOHEADER:-autoheader} --version 2>/dev/null|head -n 1| sed -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'`
-if test -z "$ah_version"; then
- echo "buildconf: autoheader not found."
- echo " You need autoheader version 2.50 or newer installed."
- exit 1
-fi
-old_IFS=$IFS; IFS='.'; set $ah_version; IFS=$old_IFS
-if test "$1" = "2" -a "$2" -lt "50" || test "$1" -lt "2"; then
- echo "buildconf: autoheader version $ah_version found."
- echo " You need autoheader version 2.50 or newer installed."
- echo " If you have a sufficient autoheader installed, but it"
- echo " is not named 'autoheader', then try setting the"
- echo " AUTOHEADER environment variable."
- exit 1
-fi
-
-echo "buildconf: autoheader version $ah_version (ok)"
-
-#--------------------------------------------------------------------------
-# automake 1.7 or newer
-#
-need_automake="1.7"
-am_version=`${AUTOMAKE:-automake} --version 2>/dev/null|head -n 1| sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//' -e 's/\(.*\)\(-p.*\)/\1/'`
-if test -z "$am_version"; then
- echo "buildconf: automake not found."
- echo " You need automake version $need_automake or newer installed."
- exit 1
-fi
-old_IFS=$IFS; IFS='.'; set $am_version; IFS=$old_IFS
-if test "$1" = "1" -a "$2" -lt "7" || test "$1" -lt "1"; then
- echo "buildconf: automake version $am_version found."
- echo " You need automake version $need_automake or newer installed."
- echo " If you have a sufficient automake installed, but it"
- echo " is not named 'automake', then try setting the"
- echo " AUTOMAKE environment variable."
- exit 1
-fi
-
-echo "buildconf: automake version $am_version (ok)"
-
-acloc_version=`${ACLOCAL:-aclocal} --version 2>/dev/null|head -n 1| sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//' -e 's/\(.*\)\(-p.*\)/\1/'`
-if test -z "$acloc_version"; then
- echo "buildconf: aclocal not found. Weird automake installation!"
- exit 1
-fi
-if test "$acloc_version" = "$am_version"; then
- echo "buildconf: aclocal version $acloc_version (ok)"
-else
- echo "buildconf: aclocal version $acloc_version (ERROR: does not match automake version)"
- exit 1
-fi
-
-#--------------------------------------------------------------------------
-# GNU libtoolize preliminary check
-#
-want_lt_major=1
-want_lt_minor=4
-want_lt_patch=2
-want_lt_version=1.4.2
-
-# This approach that tries 'glibtoolize' first is intended for systems that
-# have GNU libtool named as 'glibtoolize' and libtoolize not being GNU's.
-
-libtoolize=`findtool glibtoolize 2>/dev/null`
-if test ! -x "$libtoolize"; then
- libtoolize=`findtool ${LIBTOOLIZE:-libtoolize}`
-fi
-if test -z "$libtoolize"; then
- echo "buildconf: libtoolize not found."
- echo " You need GNU libtoolize $want_lt_version or newer installed."
- exit 1
-fi
-
-lt_pver=`$libtoolize --version 2>/dev/null|head -n 1`
-lt_qver=`echo $lt_pver|sed -e "s/([^)]*)//g" -e "s/^[^0-9]*//g"`
-lt_version=`echo $lt_qver|sed -e "s/[- ].*//" -e "s/\([a-z]*\)$//"`
-if test -z "$lt_version"; then
- echo "buildconf: libtoolize not found."
- echo " You need GNU libtoolize $want_lt_version or newer installed."
- exit 1
-fi
-old_IFS=$IFS; IFS='.'; set $lt_version; IFS=$old_IFS
-lt_major=$1
-lt_minor=$2
-lt_patch=$3
-
-if test -z "$lt_major"; then
- lt_status="bad"
-elif test "$lt_major" -gt "$want_lt_major"; then
- lt_status="good"
-elif test "$lt_major" -lt "$want_lt_major"; then
- lt_status="bad"
-elif test -z "$lt_minor"; then
- lt_status="bad"
-elif test "$lt_minor" -gt "$want_lt_minor"; then
- lt_status="good"
-elif test "$lt_minor" -lt "$want_lt_minor"; then
- lt_status="bad"
-elif test -z "$lt_patch"; then
- lt_status="bad"
-elif test "$lt_patch" -gt "$want_lt_patch"; then
- lt_status="good"
-elif test "$lt_patch" -lt "$want_lt_patch"; then
- lt_status="bad"
-else
- lt_status="good"
-fi
-if test "$lt_status" != "good"; then
- echo "buildconf: libtoolize version $lt_version found."
- echo " You need GNU libtoolize $want_lt_version or newer installed."
- exit 1
-fi
-
-echo "buildconf: libtoolize version $lt_version (ok)"
-
-#--------------------------------------------------------------------------
-# m4 check
-#
-m4=`(${M4:-m4} --version 0<&- || ${M4:-gm4} --version) 2>/dev/null 0<&- | head -n 1`;
-m4_version=`echo $m4 | sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//'`
-
-if { echo $m4 | grep "GNU" >/dev/null 2>&1; } then
- echo "buildconf: GNU m4 version $m4_version (ok)"
-else
- if test -z "$m4"; then
- echo "buildconf: m4 version not recognized. You need a GNU m4 or compatible installed!"
- else
- echo "buildconf: m4 version $m4 found. You need a GNU m4 or compatible installed!"
- fi
- # Early testing on NetBSD 8.0 showed that the hard failure here is
- # overkill, at least for gnurl.
- # exit 1
-fi
-
-#--------------------------------------------------------------------------
-# perl check
-#
-PERL=`findtool ${PERL:-perl}`
-if test -z "$PERL"; then
- echo "buildconf: perl not found"
- exit 1
-fi
-
-#--------------------------------------------------------------------------
-# Remove files generated on previous buildconf/configure run.
-#
-for fname in .deps \
- .libs \
- *.la \
- *.lo \
- *.a \
- *.o \
- Makefile \
- Makefile.in \
- aclocal.m4 \
- aclocal.m4.bak \
- autom4te.cache \
- compile \
- config.guess \
- curl_config.h \
- curl_config.h.in \
- config.log \
- config.lt \
- config.status \
- config.sub \
- configure \
- configurehelp.pm \
- gnurl-config \
- depcomp \
- libcares.pc \
- libcurl.pc \
- libtool \
- libtool.m4 \
- libtool.m4.tmp \
- ltmain.sh \
- ltoptions.m4 \
- ltsugar.m4 \
- ltversion.m4 \
- lt~obsolete.m4 \
- missing \
- install-sh \
- stamp-h1 \
- stamp-h2 \
- stamp-h3 ; do
- removethis "$fname"
-done
-
-#--------------------------------------------------------------------------
-# run the correct scripts now
-#
-
-echo "buildconf: running libtoolize"
-${libtoolize} --copy --force || die "libtoolize command failed"
-
-# When using libtool 1.5.X (X < 26) we copy libtool.m4 to our local m4
-# subdirectory and this local copy is patched to fix some warnings that
-# are triggered when running aclocal and using autoconf 2.62 or later.
-
-if test "$lt_major" = "1" && test "$lt_minor" = "5"; then
- if test -z "$lt_patch" || test "$lt_patch" -lt "26"; then
- echo "buildconf: copying libtool.m4 to local m4 subdir"
- ac_dir=`${ACLOCAL:-aclocal} --print-ac-dir`
- if test -f $ac_dir/libtool.m4; then
- cp -f $ac_dir/libtool.m4 m4/libtool.m4
- else
- echo "buildconf: $ac_dir/libtool.m4 not found"
- fi
- if test -f m4/libtool.m4; then
- echo "buildconf: renaming some variables in local m4/libtool.m4"
- $PERL -i.tmp -pe \
- 's/lt_prog_compiler_pic_works/lt_cv_prog_compiler_pic_works/g; \
- s/lt_prog_compiler_static_works/lt_cv_prog_compiler_static_works/g;' \
- m4/libtool.m4
- rm -f m4/libtool.m4.tmp
- fi
- fi
-fi
-
-if test -f m4/libtool.m4; then
- echo "buildconf: converting all mv to mv -f in local m4/libtool.m4"
- $PERL -i.tmp -pe 's/\bmv +([^-\s])/mv -f $1/g' m4/libtool.m4
- rm -f m4/libtool.m4.tmp
-fi
-
-echo "buildconf: running aclocal"
-#shellcheck disable=SC2154
-${ACLOCAL:-aclocal} -I m4 $ACLOCAL_FLAGS || die "aclocal command failed"
-
-echo "buildconf: converting all mv to mv -f in local aclocal.m4"
-$PERL -i.bak -pe 's/\bmv +([^-\s])/mv -f $1/g' aclocal.m4
-
-echo "buildconf: running autoheader"
-${AUTOHEADER:-autoheader} || die "autoheader command failed"
-
-echo "buildconf: running autoconf"
-${AUTOCONF:-autoconf} || die "autoconf command failed"
-
-echo "buildconf: running automake"
-${AUTOMAKE:-automake} --add-missing --copy || die "automake command failed"
-
-#--------------------------------------------------------------------------
-# GNU libtool complementary check
-#
-# Depending on the libtool and automake versions being used, config.guess
-# might not be installed in the subdirectory until automake has finished.
-# So we can not attempt to use it until this very last buildconf stage.
-#
-if test ! -f ./config.guess; then
- echo "buildconf: config.guess not found"
-else
- buildhost=`./config.guess 2>/dev/null|head -n 1`
- case $buildhost in
- *-*-darwin*)
- need_lt_major=1
- need_lt_minor=5
- need_lt_patch=26
- need_lt_check="yes"
- ;;
- *-*-hpux*)
- need_lt_major=1
- need_lt_minor=5
- need_lt_patch=24
- need_lt_check="yes"
- ;;
- esac
- if test ! -z "$need_lt_check"; then
- if test -z "$lt_major"; then
- lt_status="bad"
- elif test "$lt_major" -gt "$need_lt_major"; then
- lt_status="good"
- elif test "$lt_major" -lt "$need_lt_major"; then
- lt_status="bad"
- elif test -z "$lt_minor"; then
- lt_status="bad"
- elif test "$lt_minor" -gt "$need_lt_minor"; then
- lt_status="good"
- elif test "$lt_minor" -lt "$need_lt_minor"; then
- lt_status="bad"
- elif test -z "$lt_patch"; then
- lt_status="bad"
- elif test "$lt_patch" -gt "$need_lt_patch"; then
- lt_status="good"
- elif test "$lt_patch" -lt "$need_lt_patch"; then
- lt_status="bad"
- else
- lt_status="good"
- fi
- if test "$lt_status" != "good"; then
- need_lt_version="$need_lt_major.$need_lt_minor.$need_lt_patch"
- echo "buildconf: libtool version $lt_version found."
- echo " $buildhost requires GNU libtool $need_lt_version or newer installed."
- rm -f configure
- exit 1
- fi
- fi
-fi
-
-#--------------------------------------------------------------------------
-# Finished successfully.
-#
-echo "buildconf: OK"
-exit 0
+echo "*** Do not use buildconf. Instead, just use: autoreconf -fi" >&2
+exec ${AUTORECONF:-autoreconf} -fi "${@}"
diff --git a/buildconf.bat b/buildconf.bat
index 043523315..13ae07e1a 100644
--- a/buildconf.bat
+++ b/buildconf.bat
@@ -10,7 +10,7 @@ rem * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
rem *
rem * This software is licensed as described in the file COPYING, which
rem * you should have received as part of this distribution. The terms
-rem * are also available at https://curl.haxx.se/docs/copyright.html.
+rem * are also available at https://curl.se/docs/copyright.html.
rem *
rem * You may opt to use, copy, modify, merge, publish, distribute and/or sell
rem * copies of the Software, and permit persons to whom the Software is
diff --git a/configure.ac b/configure.ac
index fb8fe15df..66b4e6635 100755
--- a/configure.ac
+++ b/configure.ac
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -24,7 +24,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.57)
dnl We don't know the version number "statically" so we use a dash here
-AC_INIT([gnurl], [-], [a suitable curl mailing list: https://curl.haxx.se/mail/])
+AC_INIT([gnurl], [-], [a suitable curl mailing list: https://curl.se/mail/])
XC_OVR_ZZ50
XC_OVR_ZZ60
@@ -49,7 +49,7 @@ CURL_CHECK_OPTION_CURLDEBUG
CURL_CHECK_OPTION_SYMBOL_HIDING
CURL_CHECK_OPTION_ARES
CURL_CHECK_OPTION_RT
-CURL_CHECK_OPTION_ESNI
+CURL_CHECK_OPTION_ECH
XC_CHECK_PATH_SEPARATOR
@@ -136,7 +136,7 @@ AC_SUBST(VERSIONNUM)
dnl Solaris pkgadd support definitions
PKGADD_PKG="HAXXcurl"
PKGADD_NAME="curl - a client that groks URLs"
-PKGADD_VENDOR="curl.haxx.se"
+PKGADD_VENDOR="curl.se"
AC_SUBST(PKGADD_PKG)
AC_SUBST(PKGADD_NAME)
AC_SUBST(PKGADD_VENDOR)
@@ -192,6 +192,12 @@ AS_IF([test "x$valgrind" = "xno"],
[Running tests with valgrind])
valgrind_msg="yes"])
+# curl_altsvc_msg="enabled";
+# ssl_backends=
+#
+#
+# enable_altsvc="yes"
+
dnl
dnl Save some initial values the user might have provided
dnl
@@ -410,6 +416,10 @@ AC_HELP_STRING([--disable-http],[Disable HTTP support]),
AC_SUBST(CURL_DISABLE_HTTP, [1])
AC_DEFINE(CURL_DISABLE_RTSP, 1, [to disable RTSP])
AC_SUBST(CURL_DISABLE_RTSP, [1])
+ dnl toggle off alt-svc too when HTTP is disabled
+ AC_DEFINE(CURL_DISABLE_ALTSVC, 1, [disable alt-svc])
+ curl_altsvc_msg="no";
+ enable_altsvc="no"
;;
*) AC_MSG_RESULT(yes)
;;
@@ -545,6 +555,7 @@ AC_HELP_STRING([--disable-proxy],[Disable proxy support]),
AC_MSG_RESULT(no)
AC_DEFINE(CURL_DISABLE_PROXY, 1, [to disable proxies])
AC_SUBST(CURL_DISABLE_PROXY, [1])
+ https_proxy="no"
;;
*) AC_MSG_RESULT(yes)
;;
@@ -726,11 +737,10 @@ AC_HELP_STRING([--disable-mqtt],[Disable MQTT support]),
[ case "$enableval" in
no)
AC_MSG_RESULT(no)
+ AC_DEFINE(CURL_DISABLE_MQTT, 1, [to disable MQTT])
+ AC_SUBST(CURL_DISABLE_MQTT, [1])
;;
*) AC_MSG_RESULT(yes)
- experimental="$experimental MQTT"
- AC_DEFINE(CURL_ENABLE_MQTT, 1, [to enable MQTT])
- AC_SUBST(CURL_ENABLE_MQTT, [1])
;;
esac ],
AC_MSG_RESULT(no)
@@ -937,14 +947,14 @@ then
])
fi
-if test "$HAVE_GETHOSTBYNAME" != "1"
+if test "$HAVE_GETHOSTBYNAME" != "1" -o "${with_amissl+set}" = set
then
dnl This is for AmigaOS with bsdsocket.library - needs testing before -lnet
AC_MSG_CHECKING([for gethostbyname for AmigaOS bsdsocket.library])
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[
-#include <proto/bsdsocket.h>
-struct Library *SocketBase = NULL;
+ #include <proto/bsdsocket.h>
+ struct Library *SocketBase = NULL;
]],[[
gethostbyname("www.dummysite.com");
]])
@@ -1832,20 +1842,14 @@ if test -z "$ssl_backends" -o "x$OPT_SSL" != xno &&
yes)
AC_MSG_ERROR([You must not build gnurl with OpenSSL, use --without-ssl!])
dnl --with-ssl (without path) used
- if test x$cross_compiling != xyes; then
- dnl only do pkg-config magic when not cross-compiling
- PKGTEST="yes"
- fi
+ PKGTEST="yes"
PREFIX_OPENSSL=/usr/local/ssl
LIB_OPENSSL="$PREFIX_OPENSSL/lib$libsuff"
;;
off)
AC_MSG_ERROR([You must not build gnurl with OpenSSL, use --without-ssl!])
dnl no --with-ssl option given, just check default places
- if test x$cross_compiling != xyes; then
- dnl only do pkg-config magic when not cross-compiling
- PKGTEST="yes"
- fi
+ PKGTEST="yes"
PREFIX_OPENSSL=
;;
*)
@@ -2561,8 +2565,12 @@ if test -z "$ssl_backends" -o "x$OPT_WOLFSSL" != xno; then
AC_DEFINE(HAVE_WOLFSSL_DES_ECB_ENCRYPT, 1,
[if you have wolfSSL_DES_ecb_encrypt])
if test -n "$addcflags"; then
- CPPFLAGS="$addcflags/wolfssl $CPPFLAGS"
- AC_MSG_NOTICE([Add $addcflags/wolfssl to CPPFLAGS])
+ dnl use a for loop to strip off whitespace
+ for f in $addcflags; do
+ CPPFLAGS="$f/wolfssl $CPPFLAGS"
+ AC_MSG_NOTICE([Add $f/wolfssl to CPPFLAGS])
+ break
+ done
else
dnl user didn't give a path, so guess/hope they installed wolfssl
dnl headers to system default location
@@ -3136,7 +3144,8 @@ if test X"$OPT_LIBSSH2" != Xno; then
CPPFLAGS="$CPPFLAGS $CPP_SSH2"
LIBS="$LIB_SSH2 $LIBS"
- AC_CHECK_LIB(ssh2, libssh2_channel_open_ex)
+ dnl check for function added in libssh2 version 1.0
+ AC_CHECK_LIB(ssh2, libssh2_session_block_directions)
AC_CHECK_HEADERS(libssh2.h,
curl_ssh_msg="enabled (libSSH2)"
@@ -3643,7 +3652,7 @@ case "$OPT_H2" in
;;
esac
-curl_h2_msg="disabled (--with-nghttp2)"
+curl_h2_msg="no (--with-nghttp2)"
if test X"$want_h2" != Xno; then
dnl backup the pre-nghttp2 variables
CLEANLDFLAGS="$LDFLAGS"
@@ -3702,7 +3711,7 @@ dnl Check for ngtcp2 (QUIC)
dnl **********************************************************************
OPT_TCP2="yes"
-curl_h3_msg="disabled (--with-ngtcp2, --with-quiche)"
+curl_h3_msg="no (--with-ngtcp2, --with-quiche)"
if test "x$disable_http" = "xyes"; then
# without HTTP, ngtcp2 is no use
@@ -3730,7 +3739,7 @@ case "$OPT_TCP2" in
;;
esac
-curl_tcp2_msg="disabled (--with-ngtcp2)"
+curl_tcp2_msg="no (--with-ngtcp2)"
if test X"$want_tcp2" != Xno; then
dnl backup the pre-ngtcp2 variables
CLEANLDFLAGS="$LDFLAGS"
@@ -3929,7 +3938,7 @@ case "$OPT_NGHTTP3" in
;;
esac
-curl_http3_msg="disabled (--with-nghttp3)"
+curl_http3_msg="no (--with-nghttp3)"
if test X"$want_nghttp3" != Xno; then
dnl backup the pre-nghttp3 variables
CLEANLDFLAGS="$LDFLAGS"
@@ -4601,6 +4610,8 @@ if test "$want_pthreads" != "no"; then
if test "$USE_THREADS_POSIX" != "1"
then
CFLAGS="$CFLAGS -pthread"
+ # assign PTHREAD for pkg-config use
+ PTHREAD=" -pthread"
AC_CHECK_LIB(pthread, pthread_create,
[USE_THREADS_POSIX=1],
[ CFLAGS="$save_CFLAGS"])
@@ -4787,6 +4798,24 @@ AC_HELP_STRING([--disable-cookies],[Disable cookies support]),
)
dnl ************************************************************
+dnl disable socketpair
+dnl
+AC_MSG_CHECKING([whether to support socketpair])
+AC_ARG_ENABLE(socketpair,
+AC_HELP_STRING([--enable-socketpair],[Enable socketpair support])
+AC_HELP_STRING([--disable-socketpair],[Disable socketpair support]),
+[ case "$enableval" in
+ no)
+ AC_MSG_RESULT(no)
+ AC_DEFINE(CURL_DISABLE_SOCKETPAIR, 1, [to disable socketpair support])
+ ;;
+ *) AC_MSG_RESULT(yes)
+ ;;
+ esac ],
+ AC_MSG_RESULT(yes)
+)
+
+dnl ************************************************************
dnl disable HTTP authentication support
dnl
AC_MSG_CHECKING([whether to support HTTP authentication])
@@ -4913,9 +4942,26 @@ AC_HELP_STRING([--disable-dnsshuffle],[Disable DNS shuffling]),
)
dnl ************************************************************
+dnl disable the curl_easy_options API
+dnl
+AC_MSG_CHECKING([whether to support curl_easy_option*])
+AC_ARG_ENABLE(get-easy-option,
+AC_HELP_STRING([--enable-get-easy-options],[Enable curl_easy_options])
+AC_HELP_STRING([--disable-get-easy-options],[Disable curl_easy_options]),
+[ case "$enableval" in
+ no)
+ AC_MSG_RESULT(no)
+ AC_DEFINE(CURL_DISABLE_GETOPTIONS, 1, [to disable curl_easy_options])
+ ;;
+ *) AC_MSG_RESULT(yes)
+ ;;
+ esac ],
+ AC_MSG_RESULT(yes)
+)
+
+dnl ************************************************************
dnl switch on/off alt-svc
dnl
-curl_altsvc_msg="no (--enable-alt-svc)";
AC_MSG_CHECKING([whether to support alt-svc])
AC_ARG_ENABLE(alt-svc,
AC_HELP_STRING([--enable-alt-svc],[Enable alt-svc support])
@@ -4923,47 +4969,68 @@ AC_HELP_STRING([--disable-alt-svc],[Disable alt-svc support]),
[ case "$enableval" in
no)
AC_MSG_RESULT(no)
+ AC_DEFINE(CURL_DISABLE_ALTSVC, 1, [disable alt-svc])
+ curl_altsvc_msg="no";
+ enable_altsvc="no"
+ ;;
+ *) AC_MSG_RESULT(yes)
+ ;;
+ esac ],
+ AC_MSG_RESULT(no)
+)
+
+dnl ************************************************************
+dnl switch on/off hsts
+dnl
+curl_hsts_msg="no (--enable-hsts)";
+AC_MSG_CHECKING([whether to support HSTS])
+AC_ARG_ENABLE(hsts,
+AC_HELP_STRING([--enable-hsts],[Enable HSTS support])
+AC_HELP_STRING([--disable-hsts],[Disable HSTS support]),
+[ case "$enableval" in
+ no)
+ AC_MSG_RESULT(no)
;;
*) AC_MSG_RESULT(yes)
- curl_altsvc_msg="enabled";
- enable_altsvc="yes"
+ curl_hsts_msg="enabled";
+ enable_hsts="yes"
;;
esac ],
AC_MSG_RESULT(no)
)
-if test "$enable_altsvc" = "yes"; then
- AC_DEFINE(USE_ALTSVC, 1, [to enable alt-svc])
- experimental="$experimental alt-svc"
+if test "$enable_hsts" = "yes"; then
+ AC_DEFINE(USE_HSTS, 1, [to enable HSTS])
+ experimental="$experimental HSTS"
fi
dnl *************************************************************
-dnl check whether ESNI support, if desired, is actually available
+dnl check whether ECH support, if desired, is actually available
dnl
-if test "x$want_esni" != "xno"; then
- AC_MSG_CHECKING([whether ESNI support is available])
+if test "x$want_ech" != "xno"; then
+ AC_MSG_CHECKING([whether ECH support is available])
dnl assume NOT and look for sufficient condition
- ESNI_ENABLED=0
- ESNI_SUPPORT=''
+ ECH_ENABLED=0
+ ECH_SUPPORT=''
- dnl OpenSSL with a chosen ESNI function should be enough
+ dnl OpenSSL with a chosen ECH function should be enough
dnl so more exhaustive checking seems unnecessary for now
if test "x$OPENSSL_ENABLED" = "x1"; then
- AC_CHECK_FUNCS(SSL_get_esni_status,
- ESNI_SUPPORT="ESNI support available (OpenSSL with SSL_get_esni_status)"
- ESNI_ENABLED=1)
+ AC_CHECK_FUNCS(SSL_get_ech_status,
+ ECH_SUPPORT="ECH support available (OpenSSL with SSL_get_ech_status)"
+ ECH_ENABLED=1)
dnl add 'elif' chain here for additional implementations
fi
dnl now deal with whatever we found
- if test "x$ESNI_ENABLED" = "x1"; then
- AC_DEFINE(USE_ESNI, 1, [if ESNI support is available])
- AC_MSG_RESULT($ESNI_SUPPORT)
- experimental="$experimental ESNI"
+ if test "x$ECH_ENABLED" = "x1"; then
+ AC_DEFINE(USE_ECH, 1, [if ECH support is available])
+ AC_MSG_RESULT($ECH_SUPPORT)
+ experimental="$experimental ECH"
else
- AC_MSG_ERROR([--enable-esni ignored: No ESNI support found])
+ AC_MSG_ERROR([--enable-ech ignored: No ECH support found])
fi
fi
@@ -4975,7 +5042,7 @@ CURL_CONFIGURE_SYMBOL_HIDING
dnl
dnl All the library dependencies put into $LIB apply to libcurl only.
dnl
-LIBCURL_LIBS=$LIBS
+LIBCURL_LIBS="$LIBS$PTHREAD"
AC_SUBST(LIBCURL_LIBS)
AC_SUBST(CURL_NETWORK_LIBS)
@@ -5053,6 +5120,9 @@ fi
if test "x$enable_altsvc" = "xyes"; then
SUPPORT_FEATURES="$SUPPORT_FEATURES alt-svc"
fi
+if test "x$enable_hsts" = "xyes"; then
+ SUPPORT_FEATURES="$SUPPORT_FEATURES HSTS"
+fi
if test "x$CURL_DISABLE_CRYPTO_AUTH" != "x1" -a \
\( "x$HAVE_GSSAPI" = "x1" -o "x$USE_WINDOWS_SSPI" = "x1" \); then
@@ -5094,13 +5164,16 @@ if test "x$CURL_WITH_MULTI_SSL" = "x1"; then
SUPPORT_FEATURES="$SUPPORT_FEATURES MultiSSL"
fi
-if test "x$OPENSSL_ENABLED" = "x1" -o "x$GNUTLS_ENABLED" = "x1" \
- -o "x$NSS_ENABLED" = "x1"; then
- SUPPORT_FEATURES="$SUPPORT_FEATURES HTTPS-proxy"
+dnl if not explictily turned off, HTTPS-proxy comes with some TLS backends
+if test "x$https_proxy" != "xno"; then
+ if test "x$OPENSSL_ENABLED" = "x1" -o "x$GNUTLS_ENABLED" = "x1" \
+ -o "x$NSS_ENABLED" = "x1"; then
+ SUPPORT_FEATURES="$SUPPORT_FEATURES HTTPS-proxy"
+ fi
fi
-if test "x$ESNI_ENABLED" = "x1"; then
- SUPPORT_FEATURES="$SUPPORT_FEATURES ESNI"
+if test "x$ECH_ENABLED" = "x1"; then
+ SUPPORT_FEATURES="$SUPPORT_FEATURES ECH"
fi
dnl replace spaces with newlines
@@ -5146,7 +5219,7 @@ fi
if test "x$CURL_DISABLE_GOPHER" != "x1"; then
SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS GOPHER"
fi
-if test "x$CURL_ENABLE_MQTT" = "x1"; then
+if test "x$CURL_DISABLE_MQTT" != "x1"; then
SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS MQTT"
fi
if test "x$CURL_DISABLE_POP3" != "x1"; then
@@ -5163,7 +5236,7 @@ if test "x$CURL_DISABLE_IMAP" != "x1"; then
fi
if test "x$CURL_DISABLE_SMB" != "x1" \
-a "x$CURL_DISABLE_CRYPTO_AUTH" != "x1" \
- -a \( "x$OPENSSL_ENABLED" = "x1" -o "x$USE_WINDOWS_SSPI" = "x1" \
+ -a \( "x$OPENSSL_ENABLED" = "x1" \
-o "x$GNUTLS_ENABLED" = "x1" -o "x$MBEDTLS_ENABLED" = "x1" \
-o "x$NSS_ENABLED" = "x1" -o "x$SECURETRANSPORT_ENABLED" = "x1" \
-o "x$WOLFSSL_NTLM" = "x1" \); then
@@ -5298,7 +5371,7 @@ AC_MSG_NOTICE([Configured to build gnurl/libgnurl:
Alt-svc: ${curl_altsvc_msg}
HTTP2: ${curl_h2_msg}
HTTP3: ${curl_h3_msg}
- ESNI: ${curl_esni_msg}
+ ECH: ${curl_ech_msg}
Protocols: ${SUPPORT_PROTOCOLS}
Features: ${SUPPORT_FEATURES}
valgrind tests: ${valgrind_msg}
diff --git a/docs/ALTSVC.md b/docs/ALTSVC.md
index 6a462bbbc..25437d6f9 100644
--- a/docs/ALTSVC.md
+++ b/docs/ALTSVC.md
@@ -1,11 +1,13 @@
# Alt-Svc
-curl features **EXPERIMENTAL** support for the Alt-Svc: HTTP header.
+curl features support for the Alt-Svc: HTTP header.
## Enable Alt-Svc in build
`./configure --enable-alt-svc`
+(enabled by default since 7.73.0)
+
## Standard
[RFC 7838](https://tools.ietf.org/html/rfc7838)
diff --git a/docs/BUGS b/docs/BUGS
deleted file mode 100644
index 480e0caec..000000000
--- a/docs/BUGS
+++ /dev/null
@@ -1,302 +0,0 @@
- _ _ ____ _
- ___| | | | _ \| |
- / __| | | | |_) | |
- | (__| |_| | _ <| |___
- \___|\___/|_| \_\_____|
-
-BUGS
-
- 1. Bugs
- 1.1 There are still bugs
- 1.2 Where to report
- 1.3 Security bugs
- 1.4 What to report
- 1.5 libcurl problems
- 1.6 Who will fix the problems
- 1.7 How to get a stack trace
- 1.8 Bugs in libcurl bindings
- 1.9 Bugs in old versions
-
- 2. Bug fixing procedure
- 2.1 What happens on first filing
- 2.2 First response
- 2.3 Not reproducible
- 2.4 Unresponsive
- 2.5 Lack of time/interest
- 2.6 KNOWN_BUGS
- 2.7 TODO
- 2.8 Closing off stalled bugs
-
-==============================================================================
-
-1.1 There are still bugs
-
- Curl and libcurl keep being developed. Adding features and changing code
- means that bugs will sneak in, no matter how hard we try not to.
-
- Of course there are lots of bugs left. And lots of misfeatures.
-
- To help us make curl the stable and solid product we want it to be, we need
- bug reports and bug fixes.
-
-1.2 Where to report
-
- If you can't fix a bug yourself and submit a fix for it, try to report an as
- detailed report as possible to a curl mailing list to allow one of us to
- have a go at a solution. You can optionally also post your bug/problem at
- curl's bug tracking system over at
-
- https://github.com/curl/curl/issues
-
- Please read the rest of this document below first before doing that!
-
- If you feel you need to ask around first, find a suitable mailing list and
- post there. The lists are available on https://curl.haxx.se/mail/
-
-1.3 Security bugs
-
- If you find a bug or problem in curl or libcurl that you think has a
- security impact, for example a bug that can put users in danger or make them
- vulnerable if the bug becomes public knowledge, then please report that bug
- using our security development process.
-
- Security related bugs or bugs that are suspected to have a security impact,
- should be reported on the curl security tracker at HackerOne:
-
- https://hackerone.com/curl
-
- This ensures that the report reaches the curl security team so that they
- first can be deal with the report away from the public to minimize the harm
- and impact it will have on existing users out there who might be using the
- vulnerable versions.
-
- The curl project's process for handling security related issues is
- documented here:
-
- https://curl.haxx.se/dev/secprocess.html
-
-1.4 What to report
-
- When reporting a bug, you should include all information that will help us
- understand what's wrong, what you expected to happen and how to repeat the
- bad behavior. You therefore need to tell us:
-
- - your operating system's name and version number
-
- - what version of curl you're using (curl -V is fine)
-
- - versions of the used libraries that libcurl is built to use
-
- - what URL you were working with (if possible), at least which protocol
-
- and anything and everything else you think matters. Tell us what you
- expected to happen, tell use what did happen, tell us how you could make it
- work another way. Dig around, try out, test. Then include all the tiny bits
- and pieces in your report. You will benefit from this yourself, as it will
- enable us to help you quicker and more accurately.
-
- Since curl deals with networks, it often helps us if you include a protocol
- debug dump with your bug report. The output you get by using the -v or
- --trace options.
-
- If curl crashed, causing a core dump (in unix), there is hardly any use to
- send that huge file to anyone of us. Unless we have an exact same system
- setup as you, we can't do much with it. Instead we ask you to get a stack
- trace and send that (much smaller) output to us instead!
-
- The address and how to subscribe to the mailing lists are detailed in the
- MANUAL file.
-
-1.5 libcurl problems
-
- When you've written your own application with libcurl to perform transfers,
- it is even more important to be specific and detailed when reporting bugs.
-
- Tell us the libcurl version and your operating system. Tell us the name and
- version of all relevant sub-components like for example the SSL library
- you're using and what name resolving your libcurl uses. If you use SFTP or
- SCP, the libssh2 version is relevant etc.
-
- Showing us a real source code example repeating your problem is the best way
- to get our attention and it will greatly increase our chances to understand
- your problem and to work on a fix (if we agree it truly is a problem).
-
- Lots of problems that appear to be libcurl problems are actually just abuses
- of the libcurl API or other malfunctions in your applications. It is advised
- that you run your problematic program using a memory debug tool like
- valgrind or similar before you post memory-related or "crashing" problems to
- us.
-
-1.6 Who will fix the problems
-
- If the problems or bugs you describe are considered to be bugs, we want to
- have the problems fixed.
-
- There are no developers in the curl project that are paid to work on bugs.
- All developers that take on reported bugs do this on a voluntary basis. We
- do it out of an ambition to keep curl and libcurl excellent products and out
- of pride.
-
- But please do not assume that you can just lump over something to us and it
- will then magically be fixed after some given time. Most often we need
- feedback and help to understand what you've experienced and how to repeat a
- problem. Then we may only be able to assist YOU to debug the problem and to
- track down the proper fix.
-
- We get reports from many people every month and each report can take a
- considerable amount of time to really go to the bottom with.
-
-1.7 How to get a stack trace
-
- First, you must make sure that you compile all sources with -g and that you
- don't 'strip' the final executable. Try to avoid optimizing the code as
- well, remove -O, -O2 etc from the compiler options.
-
- Run the program until it cores.
-
- Run your debugger on the core file, like '<debugger> curl core'. <debugger>
- should be replaced with the name of your debugger, in most cases that will
- be 'gdb', but 'dbx' and others also occur.
-
- When the debugger has finished loading the core file and presents you a
- prompt, enter 'where' (without the quotes) and press return.
-
- The list that is presented is the stack trace. If everything worked, it is
- supposed to contain the chain of functions that were called when curl
- crashed. Include the stack trace with your detailed bug report. It'll help a
- lot.
-
-1.8 Bugs in libcurl bindings
-
- There will of course pop up bugs in libcurl bindings. You should then
- primarily approach the team that works on that particular binding and see
- what you can do to help them fix the problem.
-
- If you suspect that the problem exists in the underlying libcurl, then
- please convert your program over to plain C and follow the steps outlined
- above.
-
-1.9 Bugs in old versions
-
- The curl project typically releases new versions every other month, and we
- fix several hundred bugs per year. For a huge table of releases, number of
- bug fixes and more, see: https://curl.haxx.se/docs/releases.html
-
- The developers in the curl project do not have bandwidth or energy enough to
- maintain several branches or to spend much time on hunting down problems in
- old versions when chances are we already fixed them or at least that they've
- changed nature and appearance in later versions.
-
- When you experience a problem and want to report it, you really SHOULD
- include the version number of the curl you're using when you experience the
- issue. If that version number shows us that you're using an out-of-date
- curl, you should also try out a modern curl version to see if the problem
- persists or how/if it has changed in appearance.
-
- Even if you cannot immediately upgrade your application/system to run the
- latest curl version, you can most often at least run a test version or
- experimental build or similar, to get this confirmed or not.
-
- At times people insist that they cannot upgrade to a modern curl version,
- but instead they "just want the bug fixed". That's fine, just don't count on
- us spending many cycles on trying to identify which single commit, if that's
- even possible, that at some point in the past fixed the problem you're now
- experiencing.
-
- Security wise, it is almost always a bad idea to lag behind the current curl
- versions by a lot. We keeping discovering and reporting security problems
- over time see you can see in this table:
- https://curl.haxx.se/docs/vulnerabilities.html
-
-2. Bug fixing procedure
-
-2.1 What happens on first filing
-
- When a new issue is posted in the issue tracker or on the mailing list, the
- team of developers first need to see the report. Maybe they took the day
- off, maybe they're off in the woods hunting. Have patience. Allow at least a
- few days before expecting someone to have responded.
-
- In the issue tracker you can expect that some labels will be set on the
- issue to help categorize it.
-
-2.2 First response
-
- If your issue/bug report wasn't perfect at once (and few are), chances are
- that someone will ask follow-up questions. Which version did you use? Which
- options did you use? How often does the problem occur? How can we reproduce
- this problem? Which protocols does it involve? Or perhaps much more specific
- and deep diving questions. It all depends on your specific issue.
-
- You should then respond to these follow-up questions and provide more info
- about the problem, so that we can help you figure it out. Or maybe you can
- help us figure it out. An active back-and-forth communication is important
- and the key for finding a cure and landing a fix.
-
-2.3 Not reproducible
-
- For problems that we can't reproduce and can't understand even after having
- gotten all the info we need and having studied the source code over again,
- are really hard to solve so then we may require further work from you who
- actually see or experience the problem.
-
-2.4 Unresponsive
-
- If the problem haven't been understood or reproduced, and there's nobody
- responding to follow-up questions or questions asking for clarifications or
- for discussing possible ways to move forward with the task, we take that as
- a strong suggestion that the bug is not important.
-
- Unimportant issues will be closed as inactive sooner or later as they can't
- be fixed. The inactivity period (waiting for responses) should not be
- shorter than two weeks but may extend months.
-
-2.5 Lack of time/interest
-
- Bugs that are filed and are understood can unfortunately end up in the
- "nobody cares enough about it to work on it" category. Such bugs are
- perfectly valid problems that *should* get fixed but apparently aren't. We
- try to mark such bugs as "KNOWN_BUGS material" after a time of inactivity
- and if no activity is noticed after yet some time those bugs are added to
- KNOWN_BUGS and are closed in the issue tracker.
-
-2.6 KNOWN_BUGS
-
- This is a list of known bugs. Bugs we know exist and that have been pointed
- out but that haven't yet been fixed. The reasons for why they haven't been
- fixed can involve anything really, but the primary reason is that nobody has
- considered these problems to be important enough to spend the necessary time
- and effort to have them fixed.
-
- The KNOWN_BUGS are always up for grabs and we will always love the ones who
- bring one of them back to live and offers solutions to them.
-
- The KNOWN_BUGS document has a sibling document known as TODO.
-
-2.7 TODO
-
- Issues that are filed or reported that aren't really bugs but more missing
- features or ideas for future improvements and so on are marked as
- 'enhancement' or 'feature-request' and will be added to the TODO document
- instead and the issue is closed. We don't keep TODO items in the issue
- tracker.
-
- The TODO document is full of ideas and suggestions of what we can add or fix
- one day. You're always encouraged and free to grab one of those items and
- take up a discussion with the curl development team on how that could be
- implemented or provided in the project so that you can work on ticking it
- odd that document.
-
- If the issue is rather a bug and not a missing feature or functionality, it
- is listed in KNOWN_BUGS instead.
-
-2.8 Closing off stalled bugs
-
- The issue and pull request trackers on https://github.com/curl/curl will
- only hold "active" entries (using a non-precise definition of what active
- actually is, but they're at least not completely dead). Those that are
- abandoned or in other ways dormant will be closed and sometimes added to
- TODO and KNOWN_BUGS instead.
-
- This way, we only have "active" issues open on github. Irrelevant issues and
- pull requests will not distract developers or casual visitors.
diff --git a/docs/BUGS.md b/docs/BUGS.md
new file mode 100644
index 000000000..c091cda75
--- /dev/null
+++ b/docs/BUGS.md
@@ -0,0 +1,266 @@
+# BUGS
+
+## There are still bugs
+
+ Curl and libcurl keep being developed. Adding features and changing code
+ means that bugs will sneak in, no matter how hard we try not to.
+
+ Of course there are lots of bugs left. And lots of misfeatures.
+
+ To help us make curl the stable and solid product we want it to be, we need
+ bug reports and bug fixes.
+
+## Where to report
+
+ If you can't fix a bug yourself and submit a fix for it, try to report an as
+ detailed report as possible to a curl mailing list to allow one of us to have
+ a go at a solution. You can optionally also submit your problem in [curl's
+ bug tracking system](https://github.com/curl/curl/issues).
+
+ Please read the rest of this document below first before doing that!
+
+ If you feel you need to ask around first, find a suitable [mailing list](
+ https://curl.se/mail/) and post your questions there.
+
+## Security bugs
+
+ If you find a bug or problem in curl or libcurl that you think has a security
+ impact, for example a bug that can put users in danger or make them
+ vulnerable if the bug becomes public knowledge, then please report that bug
+ using our security development process.
+
+ Security related bugs or bugs that are suspected to have a security impact,
+ should be reported on the [curl security tracker at
+ HackerOne](https://hackerone.com/curl).
+
+ This ensures that the report reaches the curl security team so that they
+ first can be deal with the report away from the public to minimize the harm
+ and impact it will have on existing users out there who might be using the
+ vulnerable versions.
+
+ The curl project's process for handling security related issues is
+ [documented separately](https://curl.se/dev/secprocess.html).
+
+## What to report
+
+ When reporting a bug, you should include all information that will help us
+ understand what's wrong, what you expected to happen and how to repeat the
+ bad behavior. You therefore need to tell us:
+
+ - your operating system's name and version number
+
+ - what version of curl you're using (`curl -V` is fine)
+
+ - versions of the used libraries that libcurl is built to use
+
+ - what URL you were working with (if possible), at least which protocol
+
+ and anything and everything else you think matters. Tell us what you expected
+ to happen, tell use what did happen, tell us how you could make it work
+ another way. Dig around, try out, test. Then include all the tiny bits and
+ pieces in your report. You will benefit from this yourself, as it will enable
+ us to help you quicker and more accurately.
+
+ Since curl deals with networks, it often helps us if you include a protocol
+ debug dump with your bug report. The output you get by using the `-v` or
+ `--trace` options.
+
+ If curl crashed, causing a core dump (in unix), there is hardly any use to
+ send that huge file to anyone of us. Unless we have an exact same system
+ setup as you, we can't do much with it. Instead we ask you to get a stack
+ trace and send that (much smaller) output to us instead!
+
+ The address and how to subscribe to the mailing lists are detailed in the
+ `MANUAL.md` file.
+
+## libcurl problems
+
+ When you've written your own application with libcurl to perform transfers,
+ it is even more important to be specific and detailed when reporting bugs.
+
+ Tell us the libcurl version and your operating system. Tell us the name and
+ version of all relevant sub-components like for example the SSL library
+ you're using and what name resolving your libcurl uses. If you use SFTP or
+ SCP, the libssh2 version is relevant etc.
+
+ Showing us a real source code example repeating your problem is the best way
+ to get our attention and it will greatly increase our chances to understand
+ your problem and to work on a fix (if we agree it truly is a problem).
+
+ Lots of problems that appear to be libcurl problems are actually just abuses
+ of the libcurl API or other malfunctions in your applications. It is advised
+ that you run your problematic program using a memory debug tool like valgrind
+ or similar before you post memory-related or "crashing" problems to us.
+
+## Who will fix the problems
+
+ If the problems or bugs you describe are considered to be bugs, we want to
+ have the problems fixed.
+
+ There are no developers in the curl project that are paid to work on bugs.
+ All developers that take on reported bugs do this on a voluntary basis. We do
+ it out of an ambition to keep curl and libcurl excellent products and out of
+ pride.
+
+ But please do not assume that you can just lump over something to us and it
+ will then magically be fixed after some given time. Most often we need
+ feedback and help to understand what you've experienced and how to repeat a
+ problem. Then we may only be able to assist YOU to debug the problem and to
+ track down the proper fix.
+
+ We get reports from many people every month and each report can take a
+ considerable amount of time to really go to the bottom with.
+
+## How to get a stack trace
+
+ First, you must make sure that you compile all sources with `-g` and that you
+ don't 'strip' the final executable. Try to avoid optimizing the code as well,
+ remove `-O`, `-O2` etc from the compiler options.
+
+ Run the program until it cores.
+
+ Run your debugger on the core file, like `<debugger> curl
+ core`. `<debugger>` should be replaced with the name of your debugger, in
+ most cases that will be `gdb`, but `dbx` and others also occur.
+
+ When the debugger has finished loading the core file and presents you a
+ prompt, enter `where` (without quotes) and press return.
+
+ The list that is presented is the stack trace. If everything worked, it is
+ supposed to contain the chain of functions that were called when curl
+ crashed. Include the stack trace with your detailed bug report. It'll help a
+ lot.
+
+## Bugs in libcurl bindings
+
+ There will of course pop up bugs in libcurl bindings. You should then
+ primarily approach the team that works on that particular binding and see
+ what you can do to help them fix the problem.
+
+ If you suspect that the problem exists in the underlying libcurl, then please
+ convert your program over to plain C and follow the steps outlined above.
+
+## Bugs in old versions
+
+ The curl project typically releases new versions every other month, and we
+ fix several hundred bugs per year. For a huge table of releases, number of
+ bug fixes and more, see: https://curl.se/docs/releases.html
+
+ The developers in the curl project do not have bandwidth or energy enough to
+ maintain several branches or to spend much time on hunting down problems in
+ old versions when chances are we already fixed them or at least that they've
+ changed nature and appearance in later versions.
+
+ When you experience a problem and want to report it, you really SHOULD
+ include the version number of the curl you're using when you experience the
+ issue. If that version number shows us that you're using an out-of-date curl,
+ you should also try out a modern curl version to see if the problem persists
+ or how/if it has changed in appearance.
+
+ Even if you cannot immediately upgrade your application/system to run the
+ latest curl version, you can most often at least run a test version or
+ experimental build or similar, to get this confirmed or not.
+
+ At times people insist that they cannot upgrade to a modern curl version, but
+ instead they "just want the bug fixed". That's fine, just don't count on us
+ spending many cycles on trying to identify which single commit, if that's
+ even possible, that at some point in the past fixed the problem you're now
+ experiencing.
+
+ Security wise, it is almost always a bad idea to lag behind the current curl
+ versions by a lot. We keeping discovering and reporting security problems
+ over time see you can see in [this
+ table](https://curl.se/docs/vulnerabilities.html)
+
+# Bug fixing procedure
+
+## What happens on first filing
+
+ When a new issue is posted in the issue tracker or on the mailing list, the
+ team of developers first need to see the report. Maybe they took the day off,
+ maybe they're off in the woods hunting. Have patience. Allow at least a few
+ days before expecting someone to have responded.
+
+ In the issue tracker you can expect that some labels will be set on the issue
+ to help categorize it.
+
+## First response
+
+ If your issue/bug report wasn't perfect at once (and few are), chances are
+ that someone will ask follow-up questions. Which version did you use? Which
+ options did you use? How often does the problem occur? How can we reproduce
+ this problem? Which protocols does it involve? Or perhaps much more specific
+ and deep diving questions. It all depends on your specific issue.
+
+ You should then respond to these follow-up questions and provide more info
+ about the problem, so that we can help you figure it out. Or maybe you can
+ help us figure it out. An active back-and-forth communication is important
+ and the key for finding a cure and landing a fix.
+
+## Not reproducible
+
+ For problems that we can't reproduce and can't understand even after having
+ gotten all the info we need and having studied the source code over again,
+ are really hard to solve so then we may require further work from you who
+ actually see or experience the problem.
+
+## Unresponsive
+
+ If the problem haven't been understood or reproduced, and there's nobody
+ responding to follow-up questions or questions asking for clarifications or
+ for discussing possible ways to move forward with the task, we take that as a
+ strong suggestion that the bug is not important.
+
+ Unimportant issues will be closed as inactive sooner or later as they can't
+ be fixed. The inactivity period (waiting for responses) should not be shorter
+ than two weeks but may extend months.
+
+## Lack of time/interest
+
+ Bugs that are filed and are understood can unfortunately end up in the
+ "nobody cares enough about it to work on it" category. Such bugs are
+ perfectly valid problems that *should* get fixed but apparently aren't. We
+ try to mark such bugs as `KNOWN_BUGS material` after a time of inactivity and
+ if no activity is noticed after yet some time those bugs are added to
+ `KNOWN_BUGS` and are closed in the issue tracker.
+
+## `KNOWN_BUGS`
+
+ This is a list of known bugs. Bugs we know exist and that have been pointed
+ out but that haven't yet been fixed. The reasons for why they haven't been
+ fixed can involve anything really, but the primary reason is that nobody has
+ considered these problems to be important enough to spend the necessary time
+ and effort to have them fixed.
+
+ The `KNOWN_BUGS` are always up for grabs and we will always love the ones who
+ bring one of them back to live and offers solutions to them.
+
+ The `KNOWN_BUGS` document has a sibling document known as `TODO`.
+
+## `TODO`
+
+ Issues that are filed or reported that aren't really bugs but more missing
+ features or ideas for future improvements and so on are marked as
+ 'enhancement' or 'feature-request' and will be added to the `TODO` document
+ instead and the issue is closed. We don't keep TODO items in the issue
+ tracker.
+
+ The `TODO` document is full of ideas and suggestions of what we can add or
+ fix one day. You're always encouraged and free to grab one of those items and
+ take up a discussion with the curl development team on how that could be
+ implemented or provided in the project so that you can work on ticking it odd
+ that document.
+
+ If the issue is rather a bug and not a missing feature or functionality, it
+ is listed in `KNOWN_BUGS` instead.
+
+## Closing off stalled bugs
+
+ The [issue and pull request trackers](https://github.com/curl/curl) only
+ holds "active" entries open (using a non-precise definition of what active
+ actually is, but they're at least not completely dead). Those that are
+ abandoned or in other ways dormant will be closed and sometimes added to
+ `TODO` and `KNOWN_BUGS` instead.
+
+ This way, we only have "active" issues open on github. Irrelevant issues and
+ pull requests will not distract developers or casual visitors.
diff --git a/docs/CHECKSRC.md b/docs/CHECKSRC.md
index 96150922b..d36763bc5 100644
--- a/docs/CHECKSRC.md
+++ b/docs/CHECKSRC.md
@@ -70,6 +70,8 @@ warnings are:
- `NOSPACEEQUALS`: An equals sign was found without preceding space. We prefer
`a = 2` and *not* `a=2`.
+- `ONELINECONDITION`: do not put the conditional block on the same line as `if()`
+
- `OPENCOMMENT`: File ended with a comment (`/*`) still "open".
- `PARENBRACE`: `){` was used without sufficient space in between.
@@ -98,7 +100,9 @@ warnings are:
- `TABS`: TAB characters are not allowed!
-- `TRAILINGSPACE`: Trailing white space on the line
+- `TRAILINGSPACE`: Trailing whitespace on the line
+
+- `TYPEDEFSTRUCT`: we frown upon (most) typedefed structs
- `UNUSEDIGNORE`: a checksrc inlined warning ignore was asked for but not used,
that's an ignore that should be removed or changed to get used.
diff --git a/docs/CIPHERS.md b/docs/CIPHERS.md
index 19aedf36f..2190ff156 100644
--- a/docs/CIPHERS.md
+++ b/docs/CIPHERS.md
@@ -1,15 +1,15 @@
# Ciphers
With curl's options
-[`CURLOPT_SSL_CIPHER_LIST`](https://curl.haxx.se/libcurl/c/CURLOPT_SSL_CIPHER_LIST.html)
+[`CURLOPT_SSL_CIPHER_LIST`](https://curl.se/libcurl/c/CURLOPT_SSL_CIPHER_LIST.html)
and
-[`--ciphers`](https://curl.haxx.se/docs/manpage.html#--ciphers)
+[`--ciphers`](https://curl.se/docs/manpage.html#--ciphers)
users can control which ciphers to consider when negotiating TLS connections.
TLS 1.3 ciphers are supported since curl 7.61 for OpenSSL 1.1.1+ with options
-[`CURLOPT_TLS13_CIPHERS`](https://curl.haxx.se/libcurl/c/CURLOPT_TLS13_CIPHERS.html)
+[`CURLOPT_TLS13_CIPHERS`](https://curl.se/libcurl/c/CURLOPT_TLS13_CIPHERS.html)
and
-[`--tls13-ciphers`](https://curl.haxx.se/docs/manpage.html#--tls13-ciphers)
+[`--tls13-ciphers`](https://curl.se/docs/manpage.html#--tls13-ciphers)
. If you are using a different SSL backend you can try setting TLS 1.3 cipher
suites by using the respective regular cipher option.
diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt
index 22863bc0f..b3230ec52 100644
--- a/docs/CMakeLists.txt
+++ b/docs/CMakeLists.txt
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/docs/CONTRIBUTE.md b/docs/CONTRIBUTE.md
index 3d4bf49e0..6b86b25c4 100644
--- a/docs/CONTRIBUTE.md
+++ b/docs/CONTRIBUTE.md
@@ -8,14 +8,14 @@ flaws or bugs.
### Join the Community
-Skip over to [https://curl.haxx.se/mail/](https://curl.haxx.se/mail/) and join
+Skip over to [https://curl.se/mail/](https://curl.se/mail/) and join
the appropriate mailing list(s). Read up on details before you post
questions. Read this file before you start sending patches! We prefer
questions sent to and discussions being held on the mailing list(s), not sent
to individuals.
Before posting to one of the curl mailing lists, please read up on the
-[mailing list etiquette](https://curl.haxx.se/mail/etiquette.html).
+[mailing list etiquette](https://curl.se/mail/etiquette.html).
We also hang out on IRC in #curl on irc.freenode.net
@@ -49,12 +49,12 @@ always provide us with your full real name when contributing!
### What To Read
Source code, the man pages, the [INTERNALS
-document](https://curl.haxx.se/dev/internals.html),
-[TODO](https://curl.haxx.se/docs/todo.html),
-[KNOWN_BUGS](https://curl.haxx.se/docs/knownbugs.html) and the [most recent
-changes](https://curl.haxx.se/dev/sourceactivity.html) in git. Just lurking on
+document](https://curl.se/dev/internals.html),
+[TODO](https://curl.se/docs/todo.html),
+[KNOWN_BUGS](https://curl.se/docs/knownbugs.html) and the [most recent
+changes](https://curl.se/dev/sourceactivity.html) in git. Just lurking on
the [curl-library mailing
-list](https://curl.haxx.se/mail/list.cgi?list=curl-library) will give you a
+list](https://curl.se/mail/list.cgi?list=curl-library) will give you a
lot of insights on what's going on right now. Asking there is a good idea too.
## Write a good patch
@@ -62,7 +62,7 @@ lot of insights on what's going on right now. Asking there is a good idea too.
### Follow code style
When writing C code, follow the
-[CODE_STYLE](https://curl.haxx.se/dev/code-style.html) already established in
+[CODE_STYLE](https://curl.se/dev/code-style.html) already established in
the project. Consistent style makes code easier to read and mistakes less
likely to happen. Run `make checksrc` before you submit anything, to make sure
you follow the basic style. That script doesn't verify everything, but if it
@@ -131,7 +131,7 @@ verified your changes.
Ideally you file a [pull request on
github](https://github.com/curl/curl/pulls), but you can also send your plain
patch to [the curl-library mailing
-list](https://curl.haxx.se/mail/list.cgi?list=curl-library).
+list](https://curl.se/mail/list.cgi?list=curl-library).
Either way, your change will be reviewed and discussed there and you will be
expected to correct flaws pointed out and update accordingly, or the change
@@ -172,6 +172,33 @@ you are expected to fix the problem. If you don't understand when the issue is
or have other problems to fix the complaint, just ask and other project
members will likely be able to help out.
+Consider the following table while looking at pull request failures:
+
+ | CI platform as shown in PR | State | What to look at next |
+ | ----------------------------------- | ------ | -------------------------- |
+ | CI / codeql | stable | quality check results |
+ | CI / fuzzing | stable | fuzzing results |
+ | CI / macos ... | stable | all errors and failures |
+ | Code scanning results / CodeQL | stable | quality check results |
+ | FreeBSD FreeBSD: ... | stable | all errors and failures |
+ | LGTM analysis: Python | stable | new findings |
+ | LGTM analysis: C/C++ | stable | new findings |
+ | buildbot/curl_winssl_ ... | stable | all errors and failures |
+ | continuous-integration/appveyor/pr | stable | all errors and failures |
+ | continuous-integration/travis-ci/pr | stable | all errors and failures |
+ | curl.curl (linux ...) | stable | all errors and failures |
+ | curl.curl (windows ...) | flaky | repetitive errors/failures |
+ | deepcode-ci-bot | stable | new findings |
+ | musedev | stable | new findings |
+
+Sometimes the tests fail due to a dependency service temporarily being offline
+or otherwise unavailable, eg. package downloads. In this case you can just
+try to update your pull requests to rerun the tests later as described below.
+
+You can update your pull requests by pushing new commits or force-pushing
+changes to existing commits. Force-pushing an amended commit without any
+actual content changed also allows you to retrigger the tests for that commit.
+
When you adjust your pull requests after review, consider squashing the
commits so that we can review the full updated version more easily.
diff --git a/docs/CURL-DISABLE.md b/docs/CURL-DISABLE.md
index 83436b473..6f703a3d9 100644
--- a/docs/CURL-DISABLE.md
+++ b/docs/CURL-DISABLE.md
@@ -1,5 +1,9 @@
# Code defines to disable features and protocols
+## CURL_DISABLE_ALTSVC
+
+Disable support for Alt-Svc: HTTP headers.
+
## CURL_DISABLE_COOKIES
Disable support for HTTP cookies.
@@ -24,6 +28,11 @@ Disable the FILE protocol
Disable the FTP (and FTPS) protocol
+## CURL_DISABLE_GETOPTIONS
+
+Disable the `curl_easy_options` API calls that lets users get information
+about existing options to `curl_easy_setopt`.
+
## CURL_DISABLE_GOPHER
Disable the GOPHER protocol.
@@ -57,6 +66,10 @@ Disable the --libcurl option from the curl tool.
Disable MIME support.
+## CURL_DISABLE_MQTT
+
+Disable MQTT support.
+
## CURL_DISABLE_NETRC
Disable the netrc parser.
@@ -97,6 +110,11 @@ Disable the SMB(S) protocols
Disable the SMTP(S) protocols
+## CURL_DISABLE_SOCKETPAIR
+
+Disable the use of socketpair internally to allow waking up and canceling
+curl_multi_poll().
+
## CURL_DISABLE_TELNET
Disable the TELNET protocol
diff --git a/docs/DYNBUF.md b/docs/DYNBUF.md
index 382c1365d..aa528ec3a 100644
--- a/docs/DYNBUF.md
+++ b/docs/DYNBUF.md
@@ -42,6 +42,12 @@ Append a C string to the end of the buffer.
Append a `printf()`-style string to the end of the buffer.
+## vaddf
+
+ CURLcode Curl_dyn_vaddf(struct dynbuf *s, const char *fmt, va_list ap);
+
+Append a `vprintf()`-style string to the end of the buffer.
+
## reset
void Curl_dyn_reset(struct dynbuf *s);
diff --git a/docs/ESNI.md b/docs/ECH.md
index 7feaa75ad..ad64a6a60 100644
--- a/docs/ESNI.md
+++ b/docs/ECH.md
@@ -1,24 +1,23 @@
-# TLS: ESNI support in curl and libcurl
+# TLS: ECH support in curl and libcurl
## Summary
-**ESNI** means **Encrypted Server Name Indication**, a TLS 1.3
-extension which is currently the subject of an
-[IETF Draft][tlsesni].
+**ECH** means **Encrypted Client Hello**, a TLS 1.3 extension which is
+currently the subject of an [IETF Draft][tlsesni]. (ECH was formerly known as
+ESNI).
-This file is intended to show the latest current state of ESNI support
+This file is intended to show the latest current state of ECH support
in **curl** and **libcurl**.
-At end of August 2019, an [experimental fork of curl][niallorcurl],
-built using an [experimental fork of OpenSSL][sftcdopenssl], which in
-turn provided an implementation of ESNI, was demonstrated
-interoperating with a server belonging to the [DEfO
-Project][defoproj].
+At end of August 2019, an [experimental fork of curl][niallorcurl], built
+using an [experimental fork of OpenSSL][sftcdopenssl], which in turn provided
+an implementation of ECH, was demonstrated interoperating with a server
+belonging to the [DEfO Project][defoproj].
Further sections here describe
- resources needed for building and demonstrating **curl** support
- for ESNI,
+ for ECH,
- progress to date,
@@ -28,18 +27,18 @@ Further sections here describe
## Resources needed
-To build and demonstrate ESNI support in **curl** and/or **libcurl**,
+To build and demonstrate ECH support in **curl** and/or **libcurl**,
you will need
-- a TLS library, supported by **libcurl**, which implements ESNI;
+- a TLS library, supported by **libcurl**, which implements ECH;
-- an edition of **curl** and/or **libcurl** which supports the ESNI
+- an edition of **curl** and/or **libcurl** which supports the ECH
implementation of the chosen TLS library;
- an environment for building and running **curl**, and at least
building **OpenSSL**;
-- a server, supporting ESNI, against which to run a demonstration
+- a server, supporting ECH, against which to run a demonstration
and perhaps a specific target URL;
- some instructions.
@@ -58,56 +57,53 @@ The following set of resources is currently known to be available.
- Details [below](#pr4011);
-- New **curl** feature: `CURL_VERSION_ESNI`;
+- New configuration option: `--enable-ech`;
-- New configuration option: `--enable-esni`;
-
-- Build-time check for availability of resources needed for ESNI
+- Build-time check for availability of resources needed for ECH
support;
-- Pre-processor symbol `USE_ESNI` for conditional compilation of
- ESNI support code, subject to configuration option and
+- Pre-processor symbol `USE_ECH` for conditional compilation of
+ ECH support code, subject to configuration option and
availability of needed resources.
## TODO
-- (next PR) Add libcurl options to set ESNI parameters.
+- (next PR) Add libcurl options to set ECH parameters.
-- (next PR) Add curl tool command line options to set ESNI parameters.
+- (next PR) Add curl tool command line options to set ECH parameters.
-- (WIP) Extend DoH functions so that published ESNI parameters can be
+- (WIP) Extend DoH functions so that published ECH parameters can be
retrieved from DNS instead of being required as options.
-- (WIP) Work with OpenSSL community to finalize ESNI API.
+- (WIP) Work with OpenSSL community to finalize ECH API.
-- Track OpenSSL ESNI API in libcurl
+- Track OpenSSL ECH API in libcurl
- Identify and implement any changes needed for CMake.
- Optimize build-time checking of available resources.
-- Encourage ESNI support work on other TLS/SSL backends.
+- Encourage ECH support work on other TLS/SSL backends.
## Additional detail
### PR 4011
-**TLS: Provide ESNI support framework for curl and libcurl**
+**TLS: Provide ECH support framework for curl and libcurl**
-The proposed change provides a framework to facilitate work to
-implement ESNI support in curl and libcurl. It is not intended
-either to provide ESNI functionality or to favour any particular
-TLS-providing backend. Specifically, the change reserves a
-feature bit for ESNI support (symbol `CURL_VERSION_ESNI`),
-implements setting and reporting of this bit, includes dummy
-book-keeping for the symbol, adds a build-time configuration
-option (`--enable-esni`), provides an extensible check for
-resources available to provide ESNI support, and defines a
-compiler pre-processor symbol (`USE_ESNI`) accordingly.
+The proposed change provides a framework to facilitate work to implement ECH
+support in curl and libcurl. It is not intended either to provide ECH
+functionality or to favour any particular TLS-providing backend. Specifically,
+the change reserves a feature bit for ECH support (symbol
+`CURL_VERSION_ECH`), implements setting and reporting of this bit, includes
+dummy book-keeping for the symbol, adds a build-time configuration option
+(`--enable-ech`), provides an extensible check for resources available to
+provide ECH support, and defines a compiler pre-processor symbol (`USE_ECH`)
+accordingly.
Proposed-by: @niallor (Niall O'Reilly)\
Encouraged-by: @sftcd (Stephen Farrell)\
-See-also: [this message](https://curl.haxx.se/mail/lib-2019-05/0108.html)
+See-also: [this message](https://curl.se/mail/lib-2019-05/0108.html)
Limitations:
- Book-keeping (symbols-in-versions) needs real release number, not 'DUMMY'.
@@ -117,7 +113,7 @@ Limitations:
- Check for available resources, although extensible, refers only to
specific work in progress ([described
here](https://github.com/sftcd/openssl/tree/master/esnistuff)) to
- implement ESNI for OpenSSL, as this is the immediate motivation
+ implement ECH for OpenSSL, as this is the immediate motivation
for the proposed change.
## References
diff --git a/docs/EXPERIMENTAL.md b/docs/EXPERIMENTAL.md
index bca2bd910..5b2d36c14 100644
--- a/docs/EXPERIMENTAL.md
+++ b/docs/EXPERIMENTAL.md
@@ -19,6 +19,6 @@ Experimental support in curl means:
## Experimental features right now
- HTTP/3 support and options
- - alt-svc support and options
- - MQTT
- CURLSSLOPT_NATIVE_CA (No configure option, feature built in when supported)
+ - HSTS support and options
+
diff --git a/docs/FAQ b/docs/FAQ
index 5679352b5..e17fee319 100644
--- a/docs/FAQ
+++ b/docs/FAQ
@@ -24,11 +24,8 @@ FAQ
1.15 How do I port libcurl to my OS?
2. Install Related Problems
- 2.1 configure doesn't find OpenSSL even when it is installed
- 2.1.1 native linker doesn't find OpenSSL
- 2.1.2 only the libssl lib is missing
+ 2.1 configure fails when using static libraries
2.2 Does curl work/build with other SSL libraries?
- 2.3 Where can I find a copy of LIBEAY32.DLL?
2.4 Does curl support SOCKS (RFC 1928) ?
3. Usage Problems
@@ -56,7 +53,6 @@ FAQ
3.22 curl -X gives me HTTP problems
4. Running Problems
- 4.1 Problems connecting to SSL servers.
4.2 Why do I get problems when I use & or % in the URL?
4.3 How can I use {, }, [ or ] to specify multiple URLs?
4.4 Why do I get downloaded data even though the web page doesn't exist?
@@ -68,9 +64,9 @@ FAQ
4.5.5 "405 Method Not Allowed"
4.5.6 "301 Moved Permanently"
4.6 Can you tell me what error code 142 means?
- 4.7 How do I keep user names and passwords secret in Curl command lines?
+ 4.7 How do I keep user names and passwords secret in curl command lines?
4.8 I found a bug!
- 4.9 Curl can't authenticate to the server that requires NTLM?
+ 4.9 curl can't authenticate to the server that requires NTLM?
4.10 My HTTP request using HEAD, PUT or DELETE doesn't work!
4.11 Why do my HTTP range requests return the full document?
4.12 Why do I get "certificate verify failed" ?
@@ -82,7 +78,6 @@ FAQ
4.18 file:// URLs containing drive letters (Windows, NetWare)
4.19 Why doesn't curl return an error when the network cable is unplugged?
4.20 curl doesn't return error for HTTP non-200 responses!
- 4.21 Why is there a HTTP/1.1 in my HTTP/2 request?
5. libcurl Issues
5.1 Is libcurl thread-safe?
@@ -129,7 +124,7 @@ FAQ
originally with URL spelled in uppercase to make it obvious it deals with
URLs. The fact it can also be pronounced 'see URL' also helped, it works as
an abbreviation for "Client URL Request Library" or why not the recursive
- version: "Curl URL Request Library".
+ version: "curl URL Request Library".
The cURL project produces two products:
@@ -185,22 +180,22 @@ FAQ
1.3 What is curl not?
- Curl is not a wget clone. That is a common misconception. Never, during
+ curl is not a wget clone. That is a common misconception. Never, during
curl's development, have we intended curl to replace wget or compete on its
- market. Curl is targeted at single-shot file transfers.
+ market. curl is targeted at single-shot file transfers.
- Curl is not a website mirroring program. If you want to use curl to mirror
- something: fine, go ahead and write a script that wraps around curl to make
- it reality (like curlmirror.pl does).
+ curl is not a website mirroring program. If you want to use curl to mirror
+ something: fine, go ahead and write a script that wraps around curl or use
+ libcurl to make it reality.
- Curl is not an FTP site mirroring program. Sure, get and send FTP with curl
+ curl is not an FTP site mirroring program. Sure, get and send FTP with curl
but if you want systematic and sequential behavior you should write a
script (or write a new program that interfaces libcurl) and do it.
- Curl is not a PHP tool, even though it works perfectly well when used from
+ curl is not a PHP tool, even though it works perfectly well when used from
or with PHP (when using the PHP/CURL module).
- Curl is not a program for a single operating system. Curl exists, compiles,
+ curl is not a program for a single operating system. curl exists, compiles,
builds and runs under a wide range of operating systems, including all
modern Unixes (and a bunch of older ones too), Windows, Amiga, BeOS, OS/2,
OS X, QNX etc.
@@ -211,12 +206,12 @@ FAQ
better. We do however believe in a few rules when it comes to the future of
curl:
- Curl -- the command line tool -- is to remain a non-graphical command line
+ curl -- the command line tool -- is to remain a non-graphical command line
tool. If you want GUIs or fancy scripting capabilities, you should look for
another tool that uses libcurl.
We do not add things to curl that other small and available tools already do
- very well at the side. Curl's output can be piped into another program or
+ very well at the side. curl's output can be piped into another program or
redirected to another file for the next program to interpret.
We focus on protocol related issues and improvements. If you want to do more
@@ -247,21 +242,22 @@ FAQ
1.6 What do you get for making curl?
- Project cURL is entirely free and open. No person gets paid for developing
- curl full time. We do this voluntarily, mostly in our spare time.
- Occasionally companies pay individual developers to work on curl, but that's
- up to each company and developer. This is not controlled by nor supervised in
- any way by the project.
+ Project cURL is entirely free and open. We do this voluntarily, mostly in
+ our spare time. Companies may pay individual developers to work on curl,
+ but that's up to each company and developer. This is not controlled by nor
+ supervised in any way by the curl project.
- We still get help from companies. Haxx provides website, bandwidth, mailing
- lists etc, GitHub hosts the primary git repository and other services like
- the bug tracker at https://github.com/curl/curl. Also again, some companies
- have sponsored certain parts of the development in the past and I hope some
- will continue to do so in the future.
+ We get help from companies. Haxx provides website, bandwidth, mailing lists
+ etc, GitHub hosts the primary git repository and other services like the bug
+ tracker at https://github.com/curl/curl. Also again, some companies have
+ sponsored certain parts of the development in the past and I hope some will
+ continue to do so in the future.
If you want to support our project, consider a donation or a banner-program
or even better: by helping us with coding, documenting or testing etc.
+ See also: https://curl.se/sponsors.html
+
1.7 What about CURL from curl.com?
During the summer of 2001, curl.com was busy advertising their client-side
@@ -282,7 +278,7 @@ FAQ
Please do not mail any single individual unless you really need to. Keep
curl-related questions on a suitable mailing list. All available mailing
lists are listed in the MANUAL document and online at
- https://curl.haxx.se/mail/
+ https://curl.se/mail/
Keeping curl-related questions and discussions on mailing lists allows
others to join in and help, to share their ideas, to contribute their
@@ -303,7 +299,7 @@ FAQ
your curl-related problems.
We list available alternatives on the curl website:
- https://curl.haxx.se/support.html
+ https://curl.se/support.html
1.10 How many are using curl?
@@ -317,21 +313,14 @@ FAQ
We don't know how many users that downloaded or installed curl and then
never use it.
- In May 2012 Daniel did a counting game and came up with a number that may
- be completely wrong or somewhat accurate. Over 500 million!
-
- See https://daniel.haxx.se/blog/2012/05/16/300m-users/
+ In 2020, we estimate that curl runs in roughly ten billion installations
+ world wide.
1.11 Why don't you update ca-bundle.crt
- The ca cert bundle that used to be shipped with curl was very outdated and
- must be replaced with an up-to-date version by anyone who wants to verify
- peers. It is no longer provided by curl. The last curl release that ever
- shipped a ca cert bundle was curl 7.18.0.
-
In the cURL project we've decided not to attempt to keep this file updated
- (or even present anymore) since deciding what to add to a ca cert bundle is
- an undertaking we've not been ready to accept, and the one we can get from
+ (or even present) since deciding what to add to a ca cert bundle is an
+ undertaking we've not been ready to accept, and the one we can get from
Mozilla is perfectly fine so there's no need to duplicate that work.
Today, with many services performed over HTTPS, every operating system
@@ -342,7 +331,7 @@ FAQ
If you want the most recent collection of ca certs that Mozilla Firefox
uses, we recommend that you extract the collection yourself from Mozilla
Firefox (by running 'make ca-bundle), or by using our online service setup
- for this purpose: https://curl.haxx.se/docs/caextract.html
+ for this purpose: https://curl.se/docs/caextract.html
1.12 I have a problem who can I chat with?
@@ -374,18 +363,16 @@ FAQ
1.14 How do I submit my patch?
- When you have made a patch or a change of whatever sort, and want to submit
- that to the project, there are a few different ways we prefer:
-
- o send a patch to the curl-library mailing list. We're many subscribers
- there and there are lots of people who can review patches, comment on them
- and "receive" them properly.
+ We strongly encourage you to submit changes and improvements directly as
+ "pull requests" on github: https://github.com/curl/curl/pulls
- o if your patch changes or fixes a bug, you can also opt to submit a bug
- report in the bug tracker and attach your patch there. There are less
- people involved there.
+ If you for any reason can't or won't deal with github, send your patch to
+ the curl-library mailing list. We're many subscribers there and there are
+ lots of people who can review patches, comment on them and "receive" them
+ properly.
- Lots of more details are found in the CONTRIBUTE and INTERNALS docs.
+ Lots of more details are found in the CONTRIBUTE.md and INTERNALS.md
+ documents.
1.15 How do I port libcurl to my OS?
@@ -403,46 +390,27 @@ FAQ
2. Install Related Problems
- 2.1 configure doesn't find OpenSSL even when it is installed
-
- This may be because of several reasons.
-
- 2.1.1 native linker doesn't find openssl
-
- Affected platforms:
- Solaris (native cc compiler)
- HPUX (native cc compiler)
- SGI IRIX (native cc compiler)
- SCO UNIX (native cc compiler)
-
- When configuring curl, I specify --with-ssl. OpenSSL is installed in
- /usr/local/ssl Configure reports SSL in /usr/local/ssl, but fails to find
- CRYPTO_lock in -lcrypto
+ 2.1 configure fails when using static libraries
- Cause: The cc for this test places the -L/usr/local/ssl/lib AFTER
- -lcrypto, so ld can't find the library. This is due to a bug in the GNU
- autoconf tool.
+ You may find that configure fails to properly detect the entire dependency
+ chain of libraries when you provide static versions of the libraries that
+ configure checks for.
- Workaround: Specifying "LDFLAGS=-L/usr/local/ssl/lib" in front of
- ./configure places the -L/usr/local/ssl/lib early enough in the command
- line to make things work
+ The reason why static libraries is much harder to deal with is that for them
+ we don't get any help but the script itself must know or check what more
+ libraries that are needed (with shared libraries, that dependency "chain" is
+ handled automatically). This is a very error-prone process and one that also
+ tends to vary over time depending on the release versions of the involved
+ components and may also differ between operating systems.
- 2.1.2 only the libssl lib is missing
+ For that reason, configure does very little attempts to actually figure this
+ out and you are instead encouraged to set LIBS and LDFLAGS accordingly when
+ you invoke configure, and point out the needed libraries and set the
+ necessary flags yourself.
- If all include files and the libcrypto lib is present, with only the
- libssl being missing according to configure, this is most likely because
- a few functions are left out from the libssl.
+ 2.2 Does curl work with other SSL libraries?
- If the function names missing include RSA or RSAREF you can be certain
- that this is because libssl requires the RSA and RSAREF libs to build.
-
- See the INSTALL file section that explains how to add those libs to
- configure. Make sure that you remove the config.cache file before you
- rerun configure with the new flags.
-
- 2.2 Does curl work/build with other SSL libraries?
-
- Curl has been written to use a generic SSL function layer internally, and
+ curl has been written to use a generic SSL function layer internally, and
that SSL functionality can then be provided by one out of many different SSL
backends.
@@ -450,22 +418,12 @@ FAQ
libressl, BoringSSL, GnuTLS, wolfSSL, NSS, mbedTLS, MesaLink, Secure
Transport (native iOS/OS X), Schannel (native Windows), GSKit (native IBM
i), or BearSSL. They all have their pros and cons, and we try to maintain a
- comparison of them here: https://curl.haxx.se/docs/ssl-compared.html
-
- 2.3 Where can I find a copy of LIBEAY32.DLL?
-
- That is an OpenSSL binary built for Windows.
-
- Curl can be built with OpenSSL to do the SSL stuff. The LIBEAY32.DLL is then
- what curl needs on a windows machine to do https:// etc. Check out the curl
- website to find accurate and up-to-date pointers to recent OpenSSL DLLs and
- other binary packages.
+ comparison of them here: https://curl.se/docs/ssl-compared.html
2.4 Does curl support SOCKS (RFC 1928) ?
Yes, SOCKS 4 and 5 are supported.
-
3. Usage problems
3.1 curl: (1) SSL is disabled, https: not supported
@@ -489,18 +447,18 @@ FAQ
3.2 How do I tell curl to resume a transfer?
- Curl supports resumed transfers both ways on both FTP and HTTP.
+ curl supports resumed transfers both ways on both FTP and HTTP.
Try the -C option.
3.3 Why doesn't my posting using -F work?
- You can't arbitrarily use -F or -d, the choice between -F or -d depends on the
- HTTP operation you need curl to do and what the web server that will receive
- your post expects.
+ You can't arbitrarily use -F or -d, the choice between -F or -d depends on
+ the HTTP operation you need curl to do and what the web server that will
+ receive your post expects.
- If the form you're trying to submit uses the type 'multipart/form-data', then
- and only then you must use the -F type. In all the most common cases, you
- should use -d which then causes a posting with the type
+ If the form you're trying to submit uses the type 'multipart/form-data',
+ then and only then you must use the -F type. In all the most common cases,
+ you should use -d which then causes a posting with the type
'application/x-www-form-urlencoded'.
This is described in some detail in the MANUAL and TheArtOfHttpScripting
@@ -548,7 +506,7 @@ FAQ
3.8 How do I tell curl to follow HTTP redirects?
- Curl does not follow so-called redirects by default. The Location: header
+ curl does not follow so-called redirects by default. The Location: header
that informs the client about this is only interpreted if you're using the
-L/--location option. As in:
@@ -564,7 +522,7 @@ FAQ
Find out more about which languages that support curl directly, and how to
install and use them, in the libcurl section of the curl website:
- https://curl.haxx.se/libcurl/
+ https://curl.se/libcurl/
All the various bindings to libcurl are made by other projects and people,
outside of the cURL project. The cURL project itself only produces libcurl
@@ -583,7 +541,7 @@ FAQ
3.10 What about SOAP, WebDAV, XML-RPC or similar protocols over HTTP?
- Curl adheres to the HTTP spec, which basically means you can play with *any*
+ curl adheres to the HTTP spec, which basically means you can play with *any*
protocol that is built on top of HTTP. Protocols such as SOAP, WEBDAV and
XML-RPC are all such ones. You can use -X to set custom requests and -H to
set custom headers (or replace internally generated ones).
@@ -635,7 +593,7 @@ FAQ
3.14 Does curl support Javascript or PAC (automated proxy config)?
- Many web pages do magic stuff using embedded Javascript. Curl and libcurl
+ Many web pages do magic stuff using embedded Javascript. curl and libcurl
have no built-in support for that, so it will be treated just like any other
contents.
@@ -698,7 +656,7 @@ FAQ
certificate. Server certificate verification is enabled by default in curl
and libcurl and is often the reason for problems as explained in FAQ entry
4.12 and the SSLCERTS document
- (https://curl.haxx.se/docs/sslcerts.html). Server certificates that are
+ (https://curl.se/docs/sslcerts.html). Server certificates that are
"self-signed" or otherwise signed by a CA that you do not have a CA cert
for, cannot be verified. If the verification during a connect fails, you are
refused access. You then need to explicitly disable the verification to
@@ -799,21 +757,6 @@ FAQ
4. Running Problems
- 4.1 Problems connecting to SSL servers.
-
- It took a very long time before we could sort out why curl had problems to
- connect to certain SSL servers when using SSLeay or OpenSSL v0.9+. The
- error sometimes showed up similar to:
-
- 16570:error:1407D071:SSL routines:SSL2_READ:bad mac decode:s2_pkt.c:233:
-
- It turned out to be because many older SSL servers don't deal with SSLv3
- requests properly. To correct this problem, tell curl to select SSLv2 from
- the command line (-2/--sslv2).
-
- There have also been examples where the remote server didn't like the SSLv2
- request and instead you had to force curl to use SSLv3 with -3/--sslv3.
-
4.2 Why do I get problems when I use & or % in the URL?
In general unix shells, the & symbol is treated specially and when used, it
@@ -850,7 +793,7 @@ FAQ
4.4 Why do I get downloaded data even though the web page doesn't exist?
- Curl asks remote servers for the page you specify. If the page doesn't exist
+ curl asks remote servers for the page you specify. If the page doesn't exist
at the server, the HTTP protocol defines how the server should respond and
that means that headers and a "page" will be returned. That's simply how
HTTP works.
@@ -909,7 +852,7 @@ FAQ
appreciate a detailed bug report from you that describes how we could go
ahead and repeat this!
- 4.7 How do I keep user names and passwords secret in Curl command lines?
+ 4.7 How do I keep user names and passwords secret in curl command lines?
This problem has two sides:
@@ -943,7 +886,7 @@ FAQ
If there is a bug, read the BUGS document first. Then report it as described
in there.
- 4.9 Curl can't authenticate to the server that requires NTLM?
+ 4.9 curl can't authenticate to the server that requires NTLM?
NTLM support requires OpenSSL, GnuTLS, mbedTLS, NSS, Secure Transport, or
Microsoft Windows libraries at build-time to provide this functionality.
@@ -969,27 +912,32 @@ FAQ
4.12 Why do I get "certificate verify failed" ?
- You invoke curl 7.10 or later to communicate on a https:// URL and get an
- error back looking something similar to this:
-
- curl: (35) SSL: error:14090086:SSL routines:
- SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
-
- Then it means that curl couldn't verify that the server's certificate was
- good. Curl verifies the certificate using the CA cert bundle that comes with
- the curl installation.
-
- To disable the verification (which makes it act like curl did before 7.10),
- use -k. This does however enable man-in-the-middle attacks.
-
- If you get this failure but are having a CA cert bundle installed and used,
- the server's certificate is not signed by one of the CA's in the bundle. It
- might for example be self-signed. You then correct this problem by obtaining
- a valid CA cert for the server. Or again, decrease the security by disabling
- this check.
-
- Details are also in the SSLCERTS file in the release archives, found online
- here: https://curl.haxx.se/docs/sslcerts.html
+ When you invoke curl and get an error 60 error back it means that curl
+ couldn't verify that the server's certificate was good. curl verifies the
+ certificate using the CA cert bundle and verifying for which names the
+ certficiate has been granted.
+
+ To completely disable the certficiate verification, use -k. This does
+ however enable man-in-the-middle attacks and makes the transfer INSECURE.
+ We strongly advice against doing this for more than experiments.
+
+ If you get this failure with a CA cert bundle installed and used, the
+ server's certificate might not be signed by one of the CA's in yout CA
+ store. It might for example be self-signed. You then correct this problem by
+ obtaining a valid CA cert for the server. Or again, decrease the security by
+ disabling this check.
+
+ At times, you find that the verification works in your favorite browser but
+ fails in curl. When this happens, the reason is usually that the server
+ sends an incomplete cert chain. The server is mandated to send all
+ "intermediate certificates" but doesn't. This typically works with browsers
+ anyway since they A) cache such certs and B) supports AIA which downloads
+ such missing certificates on demand. This is a server misconfiguration. A
+ good way to figure out if this is the case it to use the SSL Labs server
+ test and check the certificate chain: https://www.ssllabs.com/ssltest/
+
+ Details are also in the SSLCERTS.md document, found online here:
+ https://curl.se/docs/sslcerts.html
4.13 Why is curl -R on Windows one hour off?
@@ -1142,17 +1090,6 @@ FAQ
You can also use the -w option and the variable %{response_code} to extract
the exact response code that was returned in the response.
- 4.21 Why is there a HTTP/1.1 in my HTTP/2 request?
-
- If you use verbose to see the HTTP request when you send off a HTTP/2
- request, it will still say 1.1.
-
- The reason for this is that we first generate the request to send using the
- old 1.1 style and show that request in the verbose output, and then we
- convert it over to the binary header-compressed HTTP/2 style. The actual
- "1.1" part from that request is then not actually used in the transfer.
- The binary HTTP/2 headers are not human readable.
-
5. libcurl Issues
5.1 Is libcurl thread-safe?
@@ -1166,7 +1103,7 @@ FAQ
There may be some exceptions to thread safety depending on how libcurl was
built. Please review the guidelines for thread safety to learn more:
- https://curl.haxx.se/libcurl/c/threadsafe.html
+ https://curl.se/libcurl/c/threadsafe.html
5.2 How can I receive all data into a large memory chunk?
@@ -1228,7 +1165,7 @@ FAQ
5.6 What about Keep-Alive or persistent connections?
curl and libcurl have excellent support for persistent connections when
- transferring several files from the same server. Curl will attempt to reuse
+ transferring several files from the same server. curl will attempt to reuse
connections for all URLs specified on the same command line/config file, and
libcurl will reuse connections for all transfers that are made using the
same libcurl handle.
@@ -1447,7 +1384,7 @@ FAQ
6. License Issues
- Curl and libcurl are released under a MIT/X derivate license. The license is
+ curl and libcurl are released under a MIT/X derivate license. The license is
very liberal and should not impose a problem for your project. This section
is just a brief summary for the cases we get the most questions. (Parts of
this section was much enhanced by Bjorn Reese.)
@@ -1521,7 +1458,7 @@ FAQ
notice" somewhere. Most probably like in the documentation or in the section
where other third party dependencies already are mentioned and acknowledged.
- As can be seen here: https://curl.haxx.se/docs/companies.html and elsewhere,
+ As can be seen here: https://curl.se/docs/companies.html and elsewhere,
more and more companies are discovering the power of libcurl and take
advantage of it even in commercial environments.
diff --git a/docs/FEATURES b/docs/FEATURES.md
index 35b26e1b2..d4278d3a8 100644
--- a/docs/FEATURES
+++ b/docs/FEATURES.md
@@ -1,21 +1,18 @@
- _ _ ____ _
- ___| | | | _ \| |
- / __| | | | |_) | |
- | (__| |_| | _ <| |___
- \___|\___/|_| \_\_____|
+# Features -- what curl can do
-FEATURES
+## curl tool
-curl tool
- config file support
- multiple URLs in a single command line
- range "globbing" support: [0-13], {one,two,three}
- multiple file upload on a single command line
- custom maximum transfer rate
- redirectable stderr
- - metalink support (*13)
+ - metalink support (13)
+ - parallel transfers
+
+## libcurl
-libcurl
- full URL syntax with no length limit
- custom maximum download time
- custom least download speed acceptable
@@ -24,28 +21,31 @@ libcurl
- uses .netrc
- progress bar with time statistics while downloading
- "standard" proxy environment variables support
- - compiles on win32 (reported builds on 40+ operating systems)
+ - compiles on win32 (reported builds on 70+ operating systems)
- selectable network interface for outgoing traffic
- IPv6 support on unix and Windows
+ - happy eyeballs dual-stack connects
- persistent connections
- - socks 4 + 5 support, with or without local name resolving
+ - SOCKS 4 + 5 support, with or without local name resolving
- supports user name and password in proxy environment variables
- - operations through proxy "tunnel" (using CONNECT)
- - support for large files (>2GB and >4GB) during upload and download
+ - operations through HTTP proxy "tunnel" (using CONNECT)
- replaceable memory functions (malloc, free, realloc, etc)
- - asynchronous name resolving (*6)
+ - asynchronous name resolving (6)
- both a push and a pull style interface
- - international domain names (*11)
+ - international domain names (11)
+
+## HTTP
-HTTP
- - HTTP/1.1 compliant (optionally uses 1.0)
+ - HTTP/0.9 responses are optionally accepted
+ - HTTP/1.0
+ - HTTP/1.1
+ - HTTP/2, including multiplexing and server push (5)
- GET
- PUT
- HEAD
- POST
- - Pipelining
- multipart formpost (RFC1867-style)
- - authentication: Basic, Digest, NTLM (*9) and Negotiate (SPNEGO) (*3)
+ - authentication: Basic, Digest, NTLM (9) and Negotiate (SPNEGO) (3)
to server and proxy
- resume (both GET and PUT)
- follow redirects
@@ -59,25 +59,27 @@ HTTP
- range
- proxy authentication
- time conditions
- - via http-proxy
+ - via HTTP proxy, HTTPS proxy or SOCKS proxy
- retrieve file modification date
- Content-Encoding support for deflate and gzip
- "Transfer-Encoding: chunked" support in uploads
- - data compression (*12)
- - HTTP/2 (*5)
+ - automatic data compression (12)
+
+## HTTPS (1)
-HTTPS (*1)
- (all the HTTP features)
+ - HTTP/3 experimental support
- using client certificates
- verify server certificate
- - via http-proxy
+ - via HTTP proxy, HTTPS proxy or SOCKS proxy
- select desired encryption
- - force usage of a specific SSL version (SSLv2 (*7), SSLv3 (*10) or TLSv1)
+ - select usage of a specific SSL version
+
+## FTP
-FTP
- download
- authentication
- - Kerberos 5 (*14)
+ - Kerberos 5 (14)
- active/passive using PORT, EPRT, PASV or EPSV
- single file size information (compare to HTTP HEAD)
- 'type=' URL support
@@ -90,52 +92,62 @@ FTP
- upload resume
- custom ftp commands (before and/or after the transfer)
- simple "range" support
- - via http-proxy
- - all operations can be tunneled through a http-proxy
+ - via HTTP proxy, HTTPS proxy or SOCKS proxy
+ - all operations can be tunneled through proxy
- customizable to retrieve file modification date
- no dir depth limit
-FTPS (*1)
- - implicit ftps:// support that use SSL on both connections
- - explicit "AUTH TLS" and "AUTH SSL" usage to "upgrade" plain ftp://
+## FTPS (1)
+
+ - implicit `ftps://` support that use SSL on both connections
+ - explicit "AUTH TLS" and "AUTH SSL" usage to "upgrade" plain `ftp://`
connection to use SSL for both or one of the connections
-SCP (*8)
+## SCP (8)
+
- both password and public key auth
-SFTP (*8)
+## SFTP (7)
+
- both password and public key auth
- with custom commands sent before/after the transfer
-TFTP
+## TFTP
+
- download
- upload
-TELNET
+## TELNET
+
- connection negotiation
- custom telnet options
- stdin/stdout I/O
-LDAP (*2)
+## LDAP (2)
+
- full LDAP URL support
-DICT
+## DICT
+
- extended DICT URL support
-FILE
+## FILE
+
- URL support
- upload
- resume
-SMB
+## SMB
+
- SMBv1 over TCP and SSL
- download
- upload
- authentication with NTLMv1
-SMTP
- - authentication: Plain, Login, CRAM-MD5, Digest-MD5, NTLM (*9), Kerberos 5
- (*4) and External.
+## SMTP
+
+ - authentication: Plain, Login, CRAM-MD5, Digest-MD5, NTLM (9), Kerberos 5
+ (4) and External.
- send e-mails
- mail from support
- mail size support
@@ -143,30 +155,34 @@ SMTP
- multiple recipients
- via http-proxy
-SMTPS (*1)
- - implicit smtps:// support
- - explicit "STARTTLS" usage to "upgrade" plain smtp:// connections to use SSL
+## SMTPS (1)
+
+ - implicit `smtps://` support
+ - explicit "STARTTLS" usage to "upgrade" plain `smtp://` connections to use SSL
- via http-proxy
-POP3
+## POP3
+
- authentication: Clear Text, APOP and SASL
- - SASL based authentication: Plain, Login, CRAM-MD5, Digest-MD5, NTLM (*9),
- Kerberos 5 (*4) and External.
+ - SASL based authentication: Plain, Login, CRAM-MD5, Digest-MD5, NTLM (9),
+ Kerberos 5 (4) and External.
- list e-mails
- retrieve e-mails
- enhanced command support for: CAPA, DELE, TOP, STAT, UIDL and NOOP via
custom requests
- via http-proxy
-POP3S (*1)
- - implicit pop3s:// support
- - explicit "STLS" usage to "upgrade" plain pop3:// connections to use SSL
+## POP3S (1)
+
+ - implicit `pop3s://` support
+ - explicit "STLS" usage to "upgrade" plain `pop3://` connections to use SSL
- via http-proxy
-IMAP
+## IMAP
+
- authentication: Clear Text and SASL
- - SASL based authentication: Plain, Login, CRAM-MD5, Digest-MD5, NTLM (*9),
- Kerberos 5 (*4) and External.
+ - SASL based authentication: Plain, Login, CRAM-MD5, Digest-MD5, NTLM (9),
+ Kerberos 5 (4) and External.
- list the folders of a mailbox
- select a mailbox with support for verifying the UIDVALIDITY
- fetch e-mails with support for specifying the UID and SECTION
@@ -175,33 +191,33 @@ IMAP
STORE, COPY and UID via custom requests
- via http-proxy
-IMAPS (*1)
- - implicit imaps:// support
- - explicit "STARTTLS" usage to "upgrade" plain imap:// connections to use SSL
+## IMAPS (1)
+
+ - implicit `imaps://` support
+ - explicit "STARTTLS" usage to "upgrade" plain `imap://` connections to use SSL
- via http-proxy
-MQTT
- - Subscribe to and publish topics using url scheme mqtt://broker/topic
-
-FOOTNOTES
-=========
-
- *1 = requires a TLS library
- *2 = requires OpenLDAP or WinLDAP
- *3 = requires a GSS-API implementation (such as Heimdal or MIT Kerberos) or
- SSPI (native Windows)
- *4 = requires a GSS-API implementation, however, only Windows SSPI is
- currently supported
- *5 = requires nghttp2 and possibly a recent TLS library
- *6 = requires c-ares
- *7 = requires OpenSSL, NSS, GSKit, Schannel or Secure Transport; GnuTLS, for
- example, only supports SSLv3 and TLSv1
- *8 = requires libssh2
- *9 = requires OpenSSL, GnuTLS, mbedTLS, NSS, yassl, Secure Transport or SSPI
- (native Windows)
- *10 = requires an SSL library that supports SSLv3
- *11 = requires libidn or Windows
- *12 = requires libz
- *13 = requires libmetalink, and either an Apple or Microsoft operating
- system, or OpenSSL, or GnuTLS, or NSS
- *14 = requires a GSS-API implementation (such as Heimdal or MIT Kerberos)
+## MQTT
+
+ - Subscribe to and publish topics using url scheme `mqtt://broker/topic`
+
+## Footnotes
+
+ 1. requires a TLS library
+ 2. requires OpenLDAP or WinLDAP
+ 3. requires a GSS-API implementation (such as Heimdal or MIT Kerberos) or
+ SSPI (native Windows)
+ 4. requires a GSS-API implementation, however, only Windows SSPI is
+ currently supported
+ 5. requires nghttp2
+ 6. requires c-ares
+ 7. requires libssh2, libssh or wolfSSH
+ 8. requires libssh2 or libssh
+ 9. requires OpenSSL, GnuTLS, mbedTLS, NSS, yassl, Secure Transport or SSPI
+ (native Windows)
+ 10. -
+ 11. requires libidn2 or Windows
+ 12. requires libz, brotli and/or zstd
+ 13. requires libmetalink, and either an Apple or Microsoft operating
+ system, or OpenSSL, or GnuTLS, or NSS
+ 14. requires a GSS-API implementation (such as Heimdal or MIT Kerberos)
diff --git a/docs/HELP-US.md b/docs/HELP-US.md
index 54744346a..b9e5b9a02 100644
--- a/docs/HELP-US.md
+++ b/docs/HELP-US.md
@@ -45,14 +45,14 @@ one that piques your interest.
Some bugs are known and haven't yet received attention and work enough to get
fixed. We collect such known existing flaws in the
-[KNOWN_BUGS](https://curl.haxx.se/docs/knownbugs.html) page. Many of them link
+[KNOWN_BUGS](https://curl.se/docs/knownbugs.html) page. Many of them link
to the original bug report with some additional details, but some may also
have aged a bit and may require some verification that the bug still exists in
the same way and that what was said about it in the past is still valid.
## Fix autobuild problems
-On the [autobuilds page](https://curl.haxx.se/dev/builds.html) we show a
+On the [autobuilds page](https://curl.se/dev/builds.html) we show a
collection of test results from the automatic curl build and tests that are
performed by volunteers. Fixing compiler warnings and errors shown there is
something we value greatly. Also, if you own or run systems or architectures
@@ -63,7 +63,7 @@ volunteers running builds automatically to help us keep curl portable.
Ideas for features and functions that we have considered worthwhile to
implement and provide are kept in the
-[TODO](https://curl.haxx.se/docs/todo.html) file. Some of the ideas are
+[TODO](https://curl.se/docs/todo.html) file. Some of the ideas are
rough. Some are well thought out. Some probably aren't really suitable
anymore.
@@ -81,7 +81,7 @@ the specific implementation. Either way is fine.
## CONTRIBUTE
-We offer [guidelines](https://curl.haxx.se/dev/contribute.html) that are
+We offer [guidelines](https://curl.se/dev/contribute.html) that are
suitable to be familiar with before you decide to contribute to curl. If
you're used to open source development, you'll probably not find many
surprises in there.
diff --git a/docs/HISTORY.md b/docs/HISTORY.md
index 4c0499f71..4f976c564 100644
--- a/docs/HISTORY.md
+++ b/docs/HISTORY.md
@@ -7,9 +7,12 @@ currency-exchange calculations available to Internet Relay Chat (IRC)
users. All the necessary data were published on the Web; he just needed to
automate their retrieval.
-Daniel simply adopted an existing command-line open-source tool, httpget, that
-Brazilian Rafael Sagula had written and recently released version 0.1 of. After
-a few minor adjustments, it did just what he needed.
+1996
+----
+
+Daniel adopted an existing command-line open-source tool, httpget, that
+Brazilian Rafael Sagula had written and recently released version 0.1
+of. After a few minor adjustments, it did just what he needed.
1997
----
@@ -126,22 +129,24 @@ impossible. Around 5000 downloaded packages each week from the main site gives
a hint, but the packages are mirrored extensively, bundled with numerous OS
distributions and otherwise retrieved as part of other software.
-September: with the release of curl 7.10 it is released under the MIT license
+October 1: with the release of curl 7.10 it is released under the MIT license
only.
+Starting with 7.10, curl verifies SSL server certificates by default.
+
2003
----
January: Started working on the distributed curl tests. The autobuilds.
February: the curl site averages at 20000 visits weekly. At any given moment,
-there's an average of 3 people browsing the curl.haxx.se site.
+there's an average of 3 people browsing the website.
Multiple new authentication schemes are supported: Digest (May), NTLM (June)
and Negotiate (June).
November: curl 7.10.8 is released. 45000 lines of code. ~55000 unique visitors
-to the curl.haxx.se site. Five official web mirrors.
+to the website. Five official web mirrors.
December: full-fledged SSL for FTP is supported.
@@ -322,6 +327,8 @@ April: added the cyassl backend (later renamed to WolfSSL)
October: SSLKEYLOGFILE support, new MIME API
+ October: Daniel received the Polhem Prize for his work on curl
+
November: brotli
2018
@@ -351,9 +358,30 @@ April: added the cyassl backend (later renamed to WolfSSL)
Public functions in libcurl: 80
Contributors: 1808
+ December: removed axTLS support
+
2019
----
+ March: added experimental alt-svc support
+
August: the first HTTP/3 requests with curl.
September: 7.66.0 is released and the tool offers parallel downloads
+
+2020
+----
+
+ curl and libcurl are installed in an estimated 10 *billion* instances
+ world-wide.
+
+ January: added BearSSL support
+
+ March: removed support for PolarSSL, added wolfSSH support
+
+ April: experimental MQTT support
+
+ August: zstd support
+
+ November: the website moves to www.curl.se. The website serves 10TB data
+ monthly.
diff --git a/docs/HSTS.md b/docs/HSTS.md
new file mode 100644
index 000000000..c3f08393c
--- /dev/null
+++ b/docs/HSTS.md
@@ -0,0 +1,44 @@
+# HSTS support
+
+curl features **EXPERIMENTAL** support for the Strict-Transport-Security: HTTP
+header. Added in curl 7.74.0
+
+## Standard
+
+[HTTP Strict Transport Security](https://tools.ietf.org/html/rfc6797)
+
+## Behavior
+
+libcurl features an in-memory cache for HSTS hosts, so that subsequent
+HTTP-only requests to a host name present in the cache will get internally
+"redirected" to the HTTPS version.
+
+## `curl_easy_setopt()` options:
+
+ - `CURLOPT_HSTS_CTRL` - enable HSTS for this easy handle
+ - `CURLOPT_HSTS` - specify file name where to store the HSTS cache on close
+ (and possibly read from at startup)
+
+## curl cmdline options
+
+ - `--hsts [filename]` - enable HSTS, use the file as HSTS cache. If filename
+ is `""` (no length) then no file will be used, only in-memory cache.
+
+## HSTS cache file format
+
+Lines starting with `#` are ignored.
+
+For each hsts entry:
+
+ [host name] "YYYYMMDD HH:MM:SS"
+
+The `[host name]` is dot-prefixed if it is a includeSubDomain.
+
+The time stamp is when the entry expires.
+
+I considered using wget's file format for the HSTS cache. However, they store the time stamp as the epoch (number of seconds since 1970) and I strongly disagree with using that format. Instead I opted to use a format similar to the curl alt-svc cache file format.
+
+## Possible future additions
+
+ - `CURLOPT_HSTS_PRELOAD` - provide a set of preloaded HSTS host names
+ - ability to save to something else than a file
diff --git a/docs/HTTP-COOKIES.md b/docs/HTTP-COOKIES.md
index de9d1de68..9d1e099d1 100644
--- a/docs/HTTP-COOKIES.md
+++ b/docs/HTTP-COOKIES.md
@@ -15,7 +15,7 @@
servers with the Cookie: header.
For a very long time, the only spec explaining how to use cookies was the
- original [Netscape spec from 1994](https://curl.haxx.se/rfc/cookie_spec.html).
+ original [Netscape spec from 1994](https://curl.se/rfc/cookie_spec.html).
In 2011, [RFC6265](https://www.ietf.org/rfc/rfc6265.txt) was finally
published and details how cookies work within HTTP. In 2016, an update which
diff --git a/docs/HTTP3.md b/docs/HTTP3.md
index 44381ae10..2a6123711 100644
--- a/docs/HTTP3.md
+++ b/docs/HTTP3.md
@@ -33,7 +33,7 @@ in the master branch using pull-requests, just like ordinary changes.
Build (patched) OpenSSL
- % git clone --depth 1 -b OpenSSL_1_1_1d-quic-draft-27 https://github.com/tatsuhiro-t/openssl
+ % git clone --depth 1 -b OpenSSL_1_1_1g-quic-draft-29 https://github.com/tatsuhiro-t/openssl
% cd openssl
% ./config enable-tls1_3 --prefix=<somewhere1>
% make
@@ -55,7 +55,7 @@ Build ngtcp2
% git clone https://github.com/ngtcp2/ngtcp2
% cd ngtcp2
% autoreconf -i
- % ./configure PKG_CONFIG_PATH=<somewhere1>/lib/pkgconfig:<somewhere2>/lib/pkgconfig LDFLAGS="-Wl,-rpath,<somewhere1>/lib" --prefix=<somewhere3>
+ % ./configure PKG_CONFIG_PATH=<somewhere1>/lib/pkgconfig:<somewhere2>/lib/pkgconfig LDFLAGS="-Wl,-rpath,<somewhere1>/lib" --prefix=<somewhere3> --enable-lib-only
% make
% make install
@@ -65,14 +65,14 @@ Build curl
% git clone https://github.com/curl/curl
% cd curl
% ./buildconf
- % LDFLAGS="-Wl,-rpath,<somewhere1>/lib" ./configure --with-ssl=<somewhere1> --with-nghttp3=<somewhere2> --with-ngtcp2=<somewhere3> --enable-alt-svc
+ % LDFLAGS="-Wl,-rpath,<somewhere1>/lib" ./configure --with-ssl=<somewhere1> --with-nghttp3=<somewhere2> --with-ngtcp2=<somewhere3>
% make
## Build with GnuTLS
-Build (patched) GnuTLS
+Build GnuTLS
- % git clone --depth 1 -b tmp-quic https://gitlab.com/gnutls/gnutls.git
+ % git clone --depth 1 https://gitlab.com/gnutls/gnutls.git
% cd gnutls
% ./bootstrap
% ./configure --disable-doc --prefix=<somewhere1>
@@ -95,7 +95,7 @@ Build ngtcp2
% git clone https://github.com/ngtcp2/ngtcp2
% cd ngtcp2
% autoreconf -i
- % ./configure PKG_CONFIG_PATH=<somewhere1>/lib/pkgconfig:<somewhere2>/lib/pkgconfig LDFLAGS="-Wl,-rpath,<somewhere1>/lib" --prefix=<somewhere3>
+ % ./configure PKG_CONFIG_PATH=<somewhere1>/lib/pkgconfig:<somewhere2>/lib/pkgconfig LDFLAGS="-Wl,-rpath,<somewhere1>/lib" --prefix=<somewhere3> --enable-lib-only
% make
% make install
@@ -105,7 +105,7 @@ Build curl
% git clone https://github.com/curl/curl
% cd curl
% ./buildconf
- % ./configure --without-ssl --with-gnutls=<somewhere1> --with-nghttp3=<somewhere2> --with-ngtcp2=<somewhere3> --enable-alt-svc
+ % ./configure --without-ssl --with-gnutls=<somewhere1> --with-nghttp3=<somewhere2> --with-ngtcp2=<somewhere3>
% make
# quiche version
@@ -126,7 +126,7 @@ Build curl:
% git clone https://github.com/curl/curl
% cd curl
% ./buildconf
- % ./configure LDFLAGS="-Wl,-rpath,$PWD/../quiche/target/release" --with-ssl=$PWD/../quiche/deps/boringssl/src --with-quiche=$PWD/../quiche/target/release --enable-alt-svc
+ % ./configure LDFLAGS="-Wl,-rpath,$PWD/../quiche/target/release" --with-ssl=$PWD/../quiche/deps/boringssl/src --with-quiche=$PWD/../quiche/target/release
% make
## Run
diff --git a/docs/INTERNALS.md b/docs/INTERNALS.md
index 635e7b2d1..9bbf63161 100644
--- a/docs/INTERNALS.md
+++ b/docs/INTERNALS.md
@@ -87,7 +87,7 @@ Dependencies
- OpenSSL 0.9.7
- GnuTLS 3.1.10
- zlib 1.1.4
- - libssh2 0.16
+ - libssh2 1.0
- c-ares 1.6.0
- libidn2 2.0.0
- wolfSSL 2.0.0
@@ -97,6 +97,7 @@ Dependencies
- NSS 3.14.x
- Heimdal ?
- nghttp2 1.12.0
+ - WinSock 2.2 (on Windows 95+ and Windows CE .NET 4.1+)
Operating Systems
-----------------
@@ -146,6 +147,8 @@ Windows vs Unix
also do it etc there might be reasons for applications to alter that
behaviour.
+ We require WinSock version 2.2 and load this version during global init.
+
3. The file descriptors for network communication and file operations are
not as easily interchangeable as in Unix.
@@ -233,11 +236,9 @@ multi_do()
The functions are named after the protocols they handle.
The protocol-specific functions of course deal with protocol-specific
- negotiations and setup. They have access to the `Curl_sendf()` (from
- `lib/sendf.c`) function to send printf-style formatted data to the remote
- host and when they're ready to make the actual file transfer they call the
- `Curl_setup_transfer()` function (in `lib/transfer.c`) to setup the
- transfer and returns.
+ negotiations and setup. When they're ready to start the actual file
+ transfer they call the `Curl_setup_transfer()` function (in
+ `lib/transfer.c`) to setup the transfer and returns.
If this DO function fails and the connection is being re-used, libcurl will
then close this connection, setup a new connection and re-issue the DO
@@ -323,9 +324,9 @@ FTP
Kerberos
========
- Kerberos support is mainly in `lib/krb5.c` and `lib/security.c` but also
- `curl_sasl_sspi.c` and `curl_sasl_gssapi.c` for the email protocols and
- `socks_gssapi.c` and `socks_sspi.c` for SOCKS5 proxy specifics.
+ Kerberos support is mainly in `lib/krb5.c` but also `curl_sasl_sspi.c` and
+ `curl_sasl_gssapi.c` for the email protocols and `socks_gssapi.c` and
+ `socks_sspi.c` for SOCKS5 proxy specifics.
<a name="telnet"></a>
TELNET
@@ -500,7 +501,7 @@ Client
status and exits.
When the operation is done, the `ourWriteOut()` function in `src/writeout.c`
- may be called to report about the operation. That function is using the
+ may be called to report about the operation. That function is mostly using the
`curl_easy_getinfo()` function to extract useful information from the curl
session.
@@ -980,8 +981,8 @@ for older and later versions as things don't change drastically that often.
protocol specific data that then gets associated with that `Curl_easy` for
the rest of this transfer. It gets freed again at the end of the transfer.
It will be called before the `connectdata` for the transfer has been
- selected/created. Most protocols will allocate its private
- `struct [PROTOCOL]` here and assign `Curl_easy->req.protop` to point to it.
+ selected/created. Most protocols will allocate its private `struct
+ [PROTOCOL]` here and assign `Curl_easy->req.p.[protocol]` to it.
`->connect_it` allows a protocol to do some specific actions after the TCP
connect is done, that can still be considered part of the connection phase.
@@ -1082,18 +1083,18 @@ for older and later versions as things don't change drastically that often.
the share API.
-[1]: https://curl.haxx.se/libcurl/c/curl_easy_setopt.html
-[2]: https://curl.haxx.se/libcurl/c/curl_easy_init.html
+[1]: https://curl.se/libcurl/c/curl_easy_setopt.html
+[2]: https://curl.se/libcurl/c/curl_easy_init.html
[3]: https://c-ares.haxx.se/
[4]: https://tools.ietf.org/html/rfc7230 "RFC 7230"
-[5]: https://curl.haxx.se/libcurl/c/CURLOPT_ACCEPT_ENCODING.html
-[6]: https://curl.haxx.se/docs/manpage.html#--compressed
-[7]: https://curl.haxx.se/libcurl/c/curl_multi_socket_action.html
-[8]: https://curl.haxx.se/libcurl/c/curl_multi_timeout.html
-[9]: https://curl.haxx.se/libcurl/c/curl_multi_setopt.html
-[10]: https://curl.haxx.se/libcurl/c/CURLMOPT_TIMERFUNCTION.html
-[11]: https://curl.haxx.se/libcurl/c/curl_multi_perform.html
-[12]: https://curl.haxx.se/libcurl/c/curl_multi_fdset.html
-[13]: https://curl.haxx.se/libcurl/c/curl_multi_add_handle.html
-[14]: https://curl.haxx.se/libcurl/c/curl_multi_info_read.html
+[5]: https://curl.se/libcurl/c/CURLOPT_ACCEPT_ENCODING.html
+[6]: https://curl.se/docs/manpage.html#--compressed
+[7]: https://curl.se/libcurl/c/curl_multi_socket_action.html
+[8]: https://curl.se/libcurl/c/curl_multi_timeout.html
+[9]: https://curl.se/libcurl/c/curl_multi_setopt.html
+[10]: https://curl.se/libcurl/c/CURLMOPT_TIMERFUNCTION.html
+[11]: https://curl.se/libcurl/c/curl_multi_perform.html
+[12]: https://curl.se/libcurl/c/curl_multi_fdset.html
+[13]: https://curl.se/libcurl/c/curl_multi_add_handle.html
+[14]: https://curl.se/libcurl/c/curl_multi_info_read.html
[15]: https://tools.ietf.org/html/rfc7231#section-3.1.2.2
diff --git a/docs/KNOWN_BUGS b/docs/KNOWN_BUGS
index e35172daf..3726f4153 100644
--- a/docs/KNOWN_BUGS
+++ b/docs/KNOWN_BUGS
@@ -25,6 +25,7 @@ problems may have been fixed or changed somewhat since this was written!
2. TLS
2.1 CURLINFO_SSL_VERIFYRESULT has limited support
2.2 DER in keychain
+ 2.3 Unable to use PKCS12 certificate with Secure Transport
2.4 Secure Transport won't import PKCS#12 client certificates without a password
2.5 Client cert handling with Issuer DN differs between backends
2.6 CURL_GLOBAL_SSL
@@ -33,6 +34,8 @@ problems may have been fixed or changed somewhat since this was written!
2.9 TLS session cache doesn't work with TFO
2.10 Store TLS context per transfer instead of per connection
2.11 Schannel TLS 1.2 handshake bug in old Windows versions
+ 2.12 FTPS with Schannel times out file list operation
+ 2.13 curl with wolfSSL lacks support for renegotiation
3. Email protocols
3.1 IMAP SEARCH ALL truncated response
@@ -52,10 +55,10 @@ problems may have been fixed or changed somewhat since this was written!
5.3 curl compiled on OSX 10.13 failed to run on OSX 10.10
5.4 Build with statically built dependency
5.5 can't handle Unicode arguments in non-Unicode builds on Windows
- 5.6 cmake support gaps
5.7 Visual Studio project gaps
5.8 configure finding libs in wrong directory
5.9 Utilize Requires.private directives in libcurl.pc
+ 5.10 SMB tests fail with Python 2
5.11 configure --with-gssapi with Heimdal is ignored on macOS
6. Authentication
@@ -104,18 +107,33 @@ problems may have been fixed or changed somewhat since this was written!
11.9 DoH doesn't inherit all transfer options
11.10 Blocking socket operations in non-blocking API
11.11 A shared connection cache is not thread-safe
+ 11.12 'no_proxy' string-matches IPv6 numerical addresses
+ 11.13 wakeup socket disconnect causes havoc
- 12. LDAP and OpenLDAP
+ 12. LDAP
12.1 OpenLDAP hangs after returning results
12.2 LDAP on Windows does authentication wrong?
12.3 LDAP on Windows doesn't work
+ 12.4 LDAPS with NSS is slow
13. TCP/IP
13.1 --interface for ipv6 binds to unusable IP address
- 14 DICT
+ 14. DICT
14.1 DICT responses show the underlying protocol
+ 15. CMake
+ 15.1 use correct SONAME
+ 15.2 support build with GnuTLS
+ 15.3 unusable tool_hugehelp.c with MinGW
+ 15.4 build docs/curl.1
+ 15.5 build on Linux links libcurl to libdl
+ 15.6 uses -lpthread instead of Threads::Threads
+ 15.7 generated .pc file contains strange entries
+ 15.8 libcurl.pc uses absolute library paths
+ 15.9 cert paths autodetected when cross-compiling
+ 15.10 libspsl is not supported
+
==============================================================================
1. HTTP
@@ -135,7 +153,7 @@ problems may have been fixed or changed somewhat since this was written!
CURLINFO_PRETRANSFER_TIME is near to zero every time.
https://github.com/curl/curl/issues/218
- https://curl.haxx.se/bug/view.cgi?id=1213
+ https://curl.se/bug/view.cgi?id=1213
1.4 multipart formposts file name encoding
@@ -150,13 +168,13 @@ problems may have been fixed or changed somewhat since this was written!
If an upload using Expect: 100-continue receives an HTTP 417 response, it
ought to be automatically resent without the Expect:. A workaround is for
the client application to redo the transfer after disabling Expect:.
- https://curl.haxx.se/mail/archive-2008-02/0043.html
+ https://curl.se/mail/archive-2008-02/0043.html
1.6 Unnecessary close when 401 received waiting for 100
libcurl closes the connection if an HTTP 401 reply is received while it is
waiting for the 100-continue response.
- https://curl.haxx.se/mail/lib-2008-08/0462.html
+ https://curl.se/mail/lib-2008-08/0462.html
1.7 Deflate error after all content was received
@@ -209,7 +227,11 @@ problems may have been fixed or changed somewhat since this was written!
2.2 DER in keychain
Curl doesn't recognize certificates in DER format in keychain, but it works
- with PEM. https://curl.haxx.se/bug/view.cgi?id=1065
+ with PEM. https://curl.se/bug/view.cgi?id=1065
+
+2.3 Unable to use PKCS12 certificate with Secure Transport
+
+ See https://github.com/curl/curl/issues/5403
2.4 Secure Transport won't import PKCS#12 client certificates without a password
@@ -285,6 +307,20 @@ problems may have been fixed or changed somewhat since this was written!
https://github.com/curl/curl/issues/5488
+2.12 FTPS with Schannel times out file list operation
+
+ "Instead of the command completing, it just sits there until the timeout
+ expires." - the same command line seems to work with other TLS backends and
+ other operating systems. See https://github.com/curl/curl/issues/5284.
+
+2.13 curl with wolfSSL lacks support for renegotiation
+
+ I am using curl (with wolfSSL) to connect https endpoint, but connection with
+ this https endpoint gets terminated because server initiates the
+ renegotiation and client does not handle renegotiation.
+
+ See https://github.com/curl/curl/issues/5839
+
3. Email protocols
3.1 IMAP SEARCH ALL truncated response
@@ -292,7 +328,7 @@ problems may have been fixed or changed somewhat since this was written!
IMAP "SEARCH ALL" truncates output on large boxes. "A quick search of the
code reveals that pingpong.c contains some truncation code, at line 408, when
it deems the server response to be too large truncating it to 40 characters"
- https://curl.haxx.se/bug/view.cgi?id=1366
+ https://curl.se/bug/view.cgi?id=1366
3.2 No disconnect command
@@ -303,7 +339,7 @@ problems may have been fixed or changed somewhat since this was written!
You have to tell libcurl not to expect a body, when dealing with one line
response commands. Please see the POP3 examples and test cases which show
- this for the NOOP and DELE commands. https://curl.haxx.se/bug/?i=740
+ this for the NOOP and DELE commands. https://curl.se/bug/?i=740
3.4 AUTH PLAIN for SMTP is not working on all servers
@@ -322,7 +358,7 @@ problems may have been fixed or changed somewhat since this was written!
decoding also means that we need to check for nastiness that is attempted,
like "../" sequences and the like. Probably everything to the left of any
embedded slashes should be cut off.
- https://curl.haxx.se/bug/view.cgi?id=1294
+ https://curl.se/bug/view.cgi?id=1294
-O also doesn't decode %-encoded names, and while it has even less
information about the charset involved the process is similar to the -J case.
@@ -337,7 +373,7 @@ problems may have been fixed or changed somewhat since this was written!
-" fails. Without -J the same command line works! This happens because the
resume logic is worked out before the target file name (and thus its
pre-transfer size) has been figured out!
- https://curl.haxx.se/bug/view.cgi?id=1169
+ https://curl.se/bug/view.cgi?id=1169
4.3 --retry and transfer timeouts
@@ -345,7 +381,7 @@ problems may have been fixed or changed somewhat since this was written!
-y/-Y) the next attempt doesn't resume the transfer properly from what was
downloaded in the previous attempt but will truncate and restart at the
original position where it was at before the previous failed attempt. See
- https://curl.haxx.se/mail/lib-2008-01/0080.html and Mandriva bug report
+ https://curl.se/mail/lib-2008-01/0080.html and Mandriva bug report
https://qa.mandriva.com/show_bug.cgi?id=22565
4.4 Improve --data-urlencode space encoding
@@ -406,25 +442,9 @@ problems may have been fixed or changed somewhat since this was written!
_UNICODE and UNICODE defined. And, except for Cygwin, Windows can't use UTF-8
as a locale.
- https://curl.haxx.se/bug/?i=345
- https://curl.haxx.se/bug/?i=731
- https://curl.haxx.se/bug/?i=3747
-
-5.6 cmake support gaps
-
- The cmake build setup lacks several features that the autoconf build
- offers. This includes:
-
- - use of correct soname for the shared library build
-
- - support for several TLS backends are missing
-
- - the unit tests cause link failures in regular non-static builds
-
- - no nghttp2 check
-
- - unusable tool_hugehelp.c with MinGW, see
- https://github.com/curl/curl/issues/3125
+ https://curl.se/bug/?i=345
+ https://curl.se/bug/?i=731
+ https://curl.se/bug/?i=3747
5.7 Visual Studio project gaps
@@ -461,6 +481,12 @@ problems may have been fixed or changed somewhat since this was written!
https://github.com/curl/curl/issues/864
+5.10 SMB tests fail with Python 2
+
+ The error message says "TreeConnectAndX not found".
+
+ See https://github.com/curl/curl/issues/5983
+
5.11 configure --with-gssapi with Heimdal is ignored on macOS
... unless you also pass --with-gssapi-libs
@@ -474,11 +500,11 @@ problems may have been fixed or changed somewhat since this was written!
NTLM authentication involving unicode user name or password only works
properly if built with UNICODE defined together with the Schannel
backend. The original problem was mentioned in:
- https://curl.haxx.se/mail/lib-2009-10/0024.html
- https://curl.haxx.se/bug/view.cgi?id=896
+ https://curl.se/mail/lib-2009-10/0024.html
+ https://curl.se/bug/view.cgi?id=896
The Schannel version verified to work as mentioned in
- https://curl.haxx.se/mail/lib-2012-07/0073.html
+ https://curl.se/mail/lib-2012-07/0073.html
6.2 MIT Kerberos for Windows build
@@ -490,7 +516,7 @@ problems may have been fixed or changed somewhat since this was written!
NTLM authentication using SSPI (on Windows) when (lib)curl is running in
"system context" will make it use wrong(?) user name - at least when compared
- to what winhttp does. See https://curl.haxx.se/bug/view.cgi?id=535
+ to what winhttp does. See https://curl.se/bug/view.cgi?id=535
6.4 Negotiate and Kerberos V5 need a fake user name
@@ -498,8 +524,8 @@ problems may have been fixed or changed somewhat since this was written!
V5 in the e-mail protocols, you need to provide a (fake) user name (this
concerns both curl and the lib) because the code wrongly only considers
authentication if there's a user name provided by setting
- conn->bits.user_passwd in url.c https://curl.haxx.se/bug/view.cgi?id=440 How?
- https://curl.haxx.se/mail/lib-2004-08/0182.html A possible solution is to
+ conn->bits.user_passwd in url.c https://curl.se/bug/view.cgi?id=440 How?
+ https://curl.se/mail/lib-2004-08/0182.html A possible solution is to
either modify this variable to be set or introduce a variable such as
new conn->bits.want_authentication which is set when any of the authentication
options are set.
@@ -541,7 +567,7 @@ problems may have been fixed or changed somewhat since this was written!
connection timeout during that phase but only the "real" timeout - which may
surprise users as it is probably considered to be the connect phase to most
people. Brought up (and is being misunderstood) in:
- https://curl.haxx.se/bug/view.cgi?id=856
+ https://curl.se/bug/view.cgi?id=856
7.2 FTP with CONNECT and slow server
@@ -555,14 +581,14 @@ problems may have been fixed or changed somewhat since this was written!
It seems sensible to be able to use CURLOPT_NOBODY and CURLOPT_FAILONERROR
with FTP to detect if a file exists or not, but it is not working:
- https://curl.haxx.se/mail/lib-2008-07/0295.html
+ https://curl.se/mail/lib-2008-07/0295.html
7.4 FTP with ACCT
When doing an operation over FTP that requires the ACCT command (but not when
logging in), the operation will fail since libcurl doesn't detect this and
thus fails to issue the correct command:
- https://curl.haxx.se/bug/view.cgi?id=635
+ https://curl.se/bug/view.cgi?id=635
7.5 ASCII FTP
@@ -634,12 +660,12 @@ problems may have been fixed or changed somewhat since this was written!
8.1 TELNET and time limitations don't work
When using telnet, the time limitation options don't work.
- https://curl.haxx.se/bug/view.cgi?id=846
+ https://curl.se/bug/view.cgi?id=846
8.2 Microsoft telnet server
There seems to be a problem when connecting to the Microsoft telnet server.
- https://curl.haxx.se/bug/view.cgi?id=649
+ https://curl.se/bug/view.cgi?id=649
9. SFTP and SCP
@@ -651,7 +677,7 @@ problems may have been fixed or changed somewhat since this was written!
instead the connection is "cancelled" (the operation is considered done)
prematurely. There is a half-baked (busy-looping) patch provided in the bug
report but it cannot be accepted as-is. See
- https://curl.haxx.se/bug/view.cgi?id=748
+ https://curl.se/bug/view.cgi?id=748
9.2 wolfssh: publickey auth doesn't work
@@ -737,7 +763,7 @@ problems may have been fixed or changed somewhat since this was written!
signal handler back into the library with a sigsetjmp, which effectively
causes libcurl to continue running within the signal handler. This is
non-portable and could cause problems on some platforms. A discussion on the
- problem is available at https://curl.haxx.se/mail/lib-2008-09/0197.html
+ problem is available at https://curl.se/mail/lib-2008-09/0197.html
Also, alarm() provides timeout resolution only to the nearest second. alarm
ought to be replaced by setitimer on systems that support it.
@@ -760,9 +786,28 @@ problems may have been fixed or changed somewhat since this was written!
handle share a connection cache, but due to how connections are used they are
still not thread-safe when used shared.
- See https://github.com/curl/curl/issues/4915
+ See https://github.com/curl/curl/issues/4915 and lib1541.c
+
+11.12 'no_proxy' string-matches IPv6 numerical addresses
+
+ This has the downside that "::1" for example doesn't match "::0:1" even
+ though they are in fact the same address.
-12. LDAP and OpenLDAP
+ See https://github.com/curl/curl/issues/5745
+
+11.13 wakeup socket disconnect causes havoc
+
+ waking an iPad breaks the wakeup socket pair, triggering a POLLIN event and
+ resulting in SOCKERRNO being set to ENOTCONN.
+
+ This condition, and other possible error conditions on the wakeup socket, are
+ not handled, so the condition remains on the FD and curl_multi_poll will
+ never block again.
+
+ See https://github.com/curl/curl/issues/6132 and
+ https://github.com/curl/curl/pull/6133
+
+12. LDAP
12.1 OpenLDAP hangs after returning results
@@ -781,7 +826,7 @@ problems may have been fixed or changed somewhat since this was written!
Generic LDAP is synchronous: OK.
See https://github.com/curl/curl/issues/622 and
- https://curl.haxx.se/mail/lib-2016-01/0101.html
+ https://curl.se/mail/lib-2016-01/0101.html
12.2 LDAP on Windows does authentication wrong?
@@ -794,6 +839,10 @@ problems may have been fixed or changed somewhat since this was written!
https://github.com/curl/curl/issues/4261
+12.4 LDAPS with NSS is slow
+
+ See https://github.com/curl/curl/issues/5874
+
13. TCP/IP
13.1 --interface for ipv6 binds to unusable IP address
@@ -812,3 +861,60 @@ problems may have been fixed or changed somewhat since this was written!
from the output.
https://github.com/curl/curl/issues/1809
+
+15. CMake
+
+15.1 use correct SONAME
+
+ The autotools build sets the SONAME properly according to VERSIONINFO in
+ lib/Makefile.am and so should cmake to make comparable build.
+
+ See https://github.com/curl/curl/pull/5935
+
+15.2 support build with GnuTLS
+
+15.3 unusable tool_hugehelp.c with MinGW
+
+ see https://github.com/curl/curl/issues/3125
+
+15.4 build docs/curl.1
+
+ The cmake build doesn't create the docs/curl.1 file and therefor must rely on
+ it being there already. This makes the --manual option not work and test
+ cases like 1139 can't function.
+
+15.5 build on Linux links libcurl to libdl
+
+ ... which it shouldn't need to!
+
+ See https://github.com/curl/curl/issues/6165
+
+15.6 uses -lpthread instead of Threads::Threads
+
+ See https://github.com/curl/curl/issues/6166
+
+15.7 generated .pc file contains strange entries
+
+ The Libs.private field of the generated .pc file contains -lgcc -lgcc_s -lc
+ -lgcc -lgcc_s
+
+ See https://github.com/curl/curl/issues/6167
+
+15.8 libcurl.pc uses absolute library paths
+
+ The libcurl.pc file generated by cmake contains things like Libs.private:
+ /usr/lib64/libssl.so /usr/lib64/libcrypto.so /usr/lib64/libz.so. The
+ autotools equivalent would say Libs.private: -lssl -lcrypto -lz
+
+ See https://github.com/curl/curl/issues/6169
+
+15.9 cert paths autodetected when cross-compiling
+
+ The autotools build disables the ca_path/ca_bundle detection when
+ cross-compiling. The cmake build keeps doing the detection.
+
+ See https://github.com/curl/curl/issues/6178
+
+15.10 libspsl is not supported
+
+ See https://github.com/curl/curl/issues/6214
diff --git a/docs/LICENSE-MIXING.md b/docs/LICENSE-MIXING.md
deleted file mode 100644
index 1083a2dcd..000000000
--- a/docs/LICENSE-MIXING.md
+++ /dev/null
@@ -1,128 +0,0 @@
-License Mixing
-==============
-
-libcurl can be built to use a fair amount of various third party libraries,
-libraries that are written and provided by other parties that are distributed
-using their own licenses. Even libcurl itself contains code that may cause
-problems to some. This document attempts to describe what licenses libcurl and
-the other libraries use and what possible dilemmas linking and mixing them all
-can lead to for end users.
-
-I am not a lawyer and this is not legal advice!
-
-One common dilemma is that [GPL](https://www.gnu.org/licenses/gpl.html)
-licensed code is not allowed to be linked with code licensed under the
-[Original BSD license](https://spdx.org/licenses/BSD-4-Clause.html) (with the
-announcement clause). You may still build your own copies that use them all,
-but distributing them as binaries would be to violate the GPL license - unless
-you accompany your license with an
-[exception](https://www.gnu.org/licenses/gpl-faq.html#GPLIncompatibleLibs). This
-particular problem was addressed when the [Modified BSD
-license](https://opensource.org/licenses/BSD-3-Clause) was created, which does
-not have the announcement clause that collides with GPL.
-
-## libcurl
-
- Uses an [MIT style license](https://curl.haxx.se/docs/copyright.html) that is
- very liberal.
-
-## OpenSSL
-
- (May be used for SSL/TLS support) Uses an Original BSD-style license with an
- announcement clause that makes it "incompatible" with GPL. You are not
- allowed to ship binaries that link with OpenSSL that includes GPL code
- (unless that specific GPL code includes an exception for OpenSSL - a habit
- that is growing more and more common). If OpenSSL's licensing is a problem
- for you, consider using another TLS library.
-
-## GnuTLS
-
- (May be used for SSL/TLS support) Uses the
- [LGPL](https://www.gnu.org/licenses/lgpl.html) license. If this is a problem
- for you, consider using another TLS library. Also note that GnuTLS itself
- depends on and uses other libs (libgcrypt and libgpg-error) and they too are
- LGPL- or GPL-licensed.
-
-## WolfSSL
-
- (May be used for SSL/TLS support) Uses the GPL license or a proprietary
- license. If this is a problem for you, consider using another TLS library.
-
-## NSS
-
- (May be used for SSL/TLS support) Is covered by the
- [MPL](https://www.mozilla.org/MPL/) license, the GPL license and the LGPL
- license. You may choose to license the code under MPL terms, GPL terms, or
- LGPL terms. These licenses grant you different permissions and impose
- different obligations. You should select the license that best meets your
- needs.
-
-## mbedTLS
-
- (May be used for SSL/TLS support) Uses the [Apache 2.0
- license](https://opensource.org/licenses/Apache-2.0) or the GPL license.
- You may choose to license the code under Apache 2.0 terms or GPL terms.
- These licenses grant you different permissions and impose different
- obligations. You should select the license that best meets your needs.
-
-## BoringSSL
-
- (May be used for SSL/TLS support) As an OpenSSL fork, it has the same
- license as that.
-
-## libressl
-
- (May be used for SSL/TLS support) As an OpenSSL fork, it has the same
- license as that.
-
-## BearSSL
-
- (May be used for SSL/TLS support) Uses an MIT license that is very liberal
- and imposes no restrictions on any other library or part you may link with.
-
-## c-ares
-
- (Used for asynchronous name resolves) Uses an MIT license that is very
- liberal and imposes no restrictions on any other library or part you may link
- with.
-
-## zlib
-
- (Used for compressed Transfer-Encoding support) Uses an MIT-style license
- that shouldn't collide with any other library.
-
-## MIT Kerberos
-
- (May be used for GSS support) MIT licensed, that shouldn't collide with any
- other parts.
-
-## Heimdal
-
- (May be used for GSS support) Heimdal is Original BSD licensed with the
- announcement clause.
-
-## GNU GSS
-
- (May be used for GSS support) GNU GSS is GPL licensed. Note that you may not
- distribute binary curl packages that uses this if you build curl to also link
- and use any Original BSD licensed libraries!
-
-## libidn
-
- (Used for IDNA support) Uses the GNU Lesser General Public License [3]. LGPL
- is a variation of GPL with slightly less aggressive "copyleft". This license
- requires more requirements to be met when distributing binaries, see the
- license for details. Also note that if you distribute a binary that includes
- this library, you must also include the full LGPL license text. Please
- properly point out what parts of the distributed package that the license
- addresses.
-
-## OpenLDAP
-
- (Used for LDAP support) Uses a Modified BSD-style license. Since libcurl uses
- OpenLDAP as a shared library only, I have not heard of anyone that ships
- OpenLDAP linked with libcurl in an app.
-
-## libssh2
-
- (Used for scp and sftp support) libssh2 uses a Modified BSD-style license.
diff --git a/docs/MAIL-ETIQUETTE b/docs/MAIL-ETIQUETTE
index 9d210a655..80d06b640 100644
--- a/docs/MAIL-ETIQUETTE
+++ b/docs/MAIL-ETIQUETTE
@@ -34,7 +34,7 @@ MAIL ETIQUETTE
1.1 Mailing Lists
The mailing lists we have are all listed and described at
- https://curl.haxx.se/mail/
+ https://curl.se/mail/
Each mailing list is targeted to a specific set of users and subjects,
please use the one or the ones that suit you the most.
diff --git a/docs/MANUAL.md b/docs/MANUAL.md
index 7063dbc8b..ca9700b2c 100644
--- a/docs/MANUAL.md
+++ b/docs/MANUAL.md
@@ -2,9 +2,9 @@
## Simple Usage
-Get the main page from Netscape's web-server:
+Get the main page from a web-server:
- curl http://www.netscape.com/
+ curl https://www.example.com/
Get the README file the user's home directory at funet's ftp-server:
@@ -16,7 +16,7 @@ Get a web page from a server using port 8000:
Get a directory listing of an FTP site:
- curl ftp://cool.haxx.se/
+ curl ftp://ftp.funet.fi
Get the definition of curl from a dictionary:
@@ -24,7 +24,7 @@ Get the definition of curl from a dictionary:
Fetch two documents at once:
- curl ftp://cool.haxx.se/ http://www.weirdserver.com:8000/
+ curl ftp://ftp.funet.fi/ http://www.weirdserver.com:8000/
Get a file off an FTPS server:
@@ -61,17 +61,17 @@ Get a file from an SMB server:
Get a web page and store in a local file with a specific name:
- curl -o thatpage.html http://www.netscape.com/
+ curl -o thatpage.html http://www.example.com/
Get a web page and store in a local file, make the local file get the name of
the remote document (if no file name part is specified in the URL, this will
fail):
- curl -O http://www.netscape.com/index.html
+ curl -O http://www.example.com/index.html
Fetch two files and store them with their remote names:
- curl -O www.haxx.se/index.html -O curl.haxx.se/download.html
+ curl -O www.haxx.se/index.html -O curl.se/download.html
## Using Passwords
@@ -273,7 +273,7 @@ will then store the headers in the specified file.
Store the HTTP headers in a separate file (headers.txt in the example):
- curl --dump-header headers.txt curl.haxx.se
+ curl --dump-header headers.txt curl.se
Note that headers stored in a separate file can be very useful at a later time
if you want curl to use cookies sent by the server. More about that in the
@@ -556,7 +556,7 @@ Example, set default time out and proxy in a config file:
# ... and we use a proxy for all accesses:
proxy = proxy.our.domain.com:8080
-White spaces ARE significant at the end of lines, but all white spaces leading
+Whitespaces ARE significant at the end of lines, but all whitespace leading
up to the first characters of each line are ignored.
Prevent curl from reading the default file by using -q as the first command
@@ -657,11 +657,11 @@ Download with `PORT` but use 192.168.0.10 as our IP address to use:
Get a web page from a server using a specified port for the interface:
- curl --interface eth0:1 http://www.netscape.com/
+ curl --interface eth0:1 http://www.example.com/
or
- curl --interface 192.168.1.10 http://www.netscape.com/
+ curl --interface 192.168.1.10 http://www.example.com/
## HTTPS
@@ -772,7 +772,7 @@ fallback mechanism in case if LDAPv3 will fail to connect.
LDAP is a complex thing and writing an LDAP query is not an easy task. I do
advise you to dig up the syntax description for that elsewhere. One such place
might be: [RFC 2255, The LDAP URL
-Format](https://curl.haxx.se/rfc/rfc2255.txt)
+Format](https://curl.se/rfc/rfc2255.txt)
To show you an example, this is how I can get all people from my local LDAP
server that has a certain sub-domain in their email address:
@@ -837,7 +837,7 @@ use it for all protocols where authentication is used.
A very simple `.netrc` file could look something like:
- machine curl.haxx.se login iamdaniel password mysecret
+ machine curl.se login iamdaniel password mysecret
## Custom Output
@@ -977,7 +977,7 @@ fail.
For your convenience, we have several open mailing lists to discuss curl, its
development and things relevant to this. Get all info at
-https://curl.haxx.se/mail/.
+https://curl.se/mail/.
Please direct curl questions, feature requests and trouble reports to one of
these mailing lists instead of mailing any individual.
diff --git a/docs/MQTT.md b/docs/MQTT.md
index a40971474..741b07297 100644
--- a/docs/MQTT.md
+++ b/docs/MQTT.md
@@ -1,25 +1,5 @@
# MQTT in curl
-## Experimental!
-
-MQTT support in curl is considered **EXPERIMENTAL** until further notice. It
-needs to be enabled at build-time. See below.
-
-After the initial merge, further development and tweaking of the MQTT support
-in curl will happen in the master branch using pull-requests, just like
-ordinary changes.
-
-Experimental support for MQTT means that we **do not guarantee** that the
-current protocol functionality will remain or remain this way going forward.
-There are no API or ABI promises for experimental features as for regular curl
-features.
-
-Do not ship anything with this enabled.
-
-## Build
-
- ./configure --enable-mqtt
-
## Usage
A plain "GET" subscribes to the topic and prints all published messages.
@@ -47,15 +27,3 @@ Remaining limitations:
- No username/password support
- No TLS (mqtts) support
- Naive EAGAIN handling won't handle split messages
-
-## Work
-
-1. Write a mqtt server for the test suite
-2. Create a few tests verifying the existing mqtt functionality
-3. Work on fixing some of the worst limitations - with accompanying tests
-4. Consider replacing the client-side MQTT code with wolfMQTT
-
-## Credits
-
-The initial MQTT patch was authored by Björn Stenberg. This work is built upon
-that patch and has been expanded since.
diff --git a/docs/Makefile.am b/docs/Makefile.am
index 820764528..376299811 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -41,7 +41,7 @@ EXTRA_DIST = \
ALTSVC.md \
BINDINGS.md \
BUG-BOUNTY.md \
- BUGS \
+ BUGS.md \
CHECKSRC.md \
CIPHERS.md \
CODE_OF_CONDUCT.md \
@@ -51,13 +51,14 @@ EXTRA_DIST = \
CURL-DISABLE.md \
DEPRECATE.md \
DYNBUF.md \
- ESNI.md \
+ ECH.md \
EXPERIMENTAL.md \
FAQ \
- FEATURES \
+ FEATURES.md \
GOVERNANCE.md \
HELP-US.md \
HISTORY.md \
+ HSTS.md \
HTTP-COOKIES.md \
HTTP2.md \
HTTP3.md \
@@ -66,21 +67,20 @@ EXTRA_DIST = \
INSTALL.md \
INTERNALS.md \
KNOWN_BUGS \
- LICENSE-MIXING.md \
MAIL-ETIQUETTE \
MQTT.md \
+ NEW-PROTOCOL.md \
options-in-versions \
PARALLEL-TRANSFERS.md \
README.md \
RELEASE-PROCEDURE.md \
- RESOURCES \
ROADMAP.md \
SECURITY-PROCESS.md \
SSL-PROBLEMS.md \
SSLCERTS.md \
THANKS \
TODO \
- TheArtOfHttpScripting \
+ TheArtOfHttpScripting.md \
VERSIONS.md
SUFFIXES = .1
diff --git a/docs/NEW-PROTOCOL.md b/docs/NEW-PROTOCOL.md
new file mode 100644
index 000000000..489c43128
--- /dev/null
+++ b/docs/NEW-PROTOCOL.md
@@ -0,0 +1,110 @@
+# Adding a new protocol?
+
+Every once in a while someone comes up with the idea of adding support for yet
+another protocol to curl. After all, curl already supports 25 something
+protocols and it is the Internet transfer machine for the world.
+
+In the curl project we love protocols and we love supporting many protocols
+and do it well.
+
+So how do you proceed to add a new protocol and what are the requirements?
+
+## No fixed set of requirements
+
+This document is an attempt to describe things to consider. There is no
+checklist of the twenty-seven things you need to cross off. We view the entire
+effort as a whole and then judge if it seems to be the right thing - for
+now. The more things that look right, fit our patterns and are done in ways
+that align with our thinking, the better are the chances that we will agree
+that supporting this protocol is a grand idea.
+
+## Mutual benefit is preferred
+
+curl is not here for your protocol. Your protocol is not here for curl. The
+best cooperation and end result occur when all involved parties mutually see
+and agree that supporting this protocol in curl would be good for everyone.
+Heck, for the world!
+
+Consider "selling us" the idea that we need an implementation merged in curl,
+to be fairly important. *Why* do we want curl to support this new protocol?
+
+## Protocol requirements
+
+### Client-side
+
+The protocol implementation is for a client's side of a "communication
+session".
+
+### Transfer oriented
+
+The protocol itself should be focused on *transfers*. Be it uploads or
+downloads or both. I should at least be possible to view the transfers as
+such, like we can view reading emails over POP3 as a downloading and sending
+emails over SMTP as an upload.
+
+If you cannot even shoehorn the protocol into a transfer focused view, then
+you are up for a tough argument.
+
+### URL
+
+There should be a documented URL format. If there is an RFC for it there is no
+question about it but the syntax doesn't have to be a published RFC. It could
+be enough if it is already in use by other implementations.
+
+If you make up the syntax just in order to be able to propose it to curl, then
+you are in a bad place. URLs are designed and defined for interoperability.
+There should at least be a good chance that other clients and servers can be
+implemented supporting the same URL syntax and work the same or similar way.
+
+URLs work on registered 'schemes'. There is a register of [all officially
+recognized
+schemes](https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml). If
+your protocol is not in there, is it really a protocol we want?
+
+### Wide and public use
+
+The protocol shall already be used or have an expectation of getting used
+widely. Experimental protocols are better off worked on in experiments first,
+to prove themselves before they are adopted by curl.
+
+## Code
+
+Of course the code needs to be written, provided, licensed agreeably and it
+should follow our code guidelines and review comments have to be dealt with.
+If the implementation needs third party code, that third party code should not
+have noticeably lesser standards than the curl project itself.
+
+## Tests
+
+As much of the protocol implementation as possible needs to be verified by
+curl test cases. We must have the implementation get tested by CI jobs,
+torture tests and more.
+
+We've experienced many times in the past how new implementations were brought
+to curl and immediately once the code had been merged, the originator vanished
+from the face of the earth. That is fine, but we need to take the necessary
+precautions so when it happens we are still fine.
+
+Our test infrastructure is powerful enough to test just about every possible
+protocol - but it might require a bit of an effort to make it happen.
+
+## Documentation
+
+We cannot assume that users are particularly familiar with specific details
+and peculiarities of the protocol. It needs documentation.
+
+Maybe it even needs some internal documentation so that the developers who
+will try to debug something five years from now can figure out functionality a
+little easier!
+
+The protocol specification itself should be freely available without requiring
+any NDA or similar.
+
+## Don't compare
+
+We are constantly raising the bar and we are constantly improving the
+project. A lot of things we did in the past would not be acceptable if done
+today. Therefore, you might be tempted to use shortcuts or "hacks" you can
+spot other - existing - protocol implementations have used, but there is
+nothing to gain from that. The bar has been raised. Former "cheats" won't be
+tolerated anymore.
diff --git a/docs/README.md b/docs/README.md
index 0521937d1..078385043 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,4 +1,4 @@
-![curl logo](https://curl.haxx.se/logo/curl-logo.svg)
+![curl logo](https://curl.se/logo/curl-logo.svg)
# Documentation
@@ -7,6 +7,6 @@ subdirectories, using several different formats. Some of them are not ideal
for reading directly in your browser.
If you'd rather see the rendered version of the documentation, check out the
-curl website's [documentation section](https://curl.haxx.se/docs/) for
-general curl stuff or the [libcurl section](https://curl.haxx.se/libcurl/) for
+curl website's [documentation section](https://curl.se/docs/) for
+general curl stuff or the [libcurl section](https://curl.se/libcurl/) for
libcurl related documentation.
diff --git a/docs/RESOURCES b/docs/RESOURCES
deleted file mode 100644
index 55f75df77..000000000
--- a/docs/RESOURCES
+++ /dev/null
@@ -1,85 +0,0 @@
- _ _ ____ _
- Project ___| | | | _ \| |
- / __| | | | |_) | |
- | (__| |_| | _ <| |___
- \___|\___/|_| \_\_____|
-
-
-This document lists documents and standards used by curl.
-
- RFC 959 - FTP Protocol
-
- RFC 1635 - How to Use Anonymous FTP
-
- RFC 1738 - Uniform Resource Locators
-
- RFC 1777 - Lightweight Directory Access Protocol (LDAP)
-
- RFC 1808 - Relative Uniform Resource Locators
-
- RFC 1867 - Form-based File Upload in HTML
-
- RFC 1950 - ZLIB Compressed Data Format Specification
-
- RFC 1951 - DEFLATE Compressed Data Format Specification
-
- RFC 1952 - GZIP File Format Specification
-
- RFC 1959 - LDAP URL Syntax
-
- RFC 2045-2049 - Everything you need to know about MIME! (needed for form
- based upload)
-
- RFC 2068 - HTTP 1.1 (obsoleted by RFC 2616)
-
- RFC 2104 - Keyed-Hashing for Message Authentication
-
- RFC 2109 - HTTP State Management Mechanism (cookie stuff)
- - Also, read Netscape's specification at
- https://curl.haxx.se/rfc/cookie_spec.html
-
- RFC 2183 - The Content-Disposition Header Field
-
- RFC 2195 - CRAM-MD5 Authentication
-
- RFC 2229 - A Dictionary Server Protocol
-
- RFC 2255 - Newer LDAP URL Format
-
- RFC 2231 - MIME Parameter Value and Encoded Word Extensions:
- Character Sets, Languages, and Continuations
-
- RFC 2388 - "Returning Values from Forms: multipart/form-data"
- Use this as an addition to the RFC1867
-
- RFC 2396 - "Uniform Resource Identifiers: Generic Syntax and Semantics" This
- one obsoletes RFC 1738, but since RFC 1738 is often mentioned
- I've left it in this list.
-
- RFC 2428 - FTP Extensions for IPv6 and NATs
-
- RFC 2577 - FTP Security Considerations
-
- RFC 2616 - HTTP 1.1, the latest
-
- RFC 2617 - HTTP Authentication
-
- RFC 2718 - Guidelines for new URL Schemes
-
- RFC 2732 - Format for Literal IPv6 Addresses in URL's
-
- RFC 2818 - HTTP Over TLS (TLS is the successor to SSL)
-
- RFC 2821 - Simple Mail Transfer Protocol (SMTP)
-
- RFC 2964 - Use of HTTP State Management
-
- RFC 2965 - HTTP State Management Mechanism. Cookies. Obsoletes RFC2109
-
- RFC 3207 - SMTP Over TLS
-
- RFC 4616 - PLAIN Authentication
-
- RFC 4954 - SMTP Authentication
-
- RFC 7932 - Brotli Compressed Data Format
diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md
index dae72a917..1a18d3e7a 100644
--- a/docs/ROADMAP.md
+++ b/docs/ROADMAP.md
@@ -8,36 +8,12 @@ participation.
HSTS
----
- Complete and merge [the existing PR](https://github.com/curl/curl/pull/2682).
+ Merge [the existing PR](https://github.com/curl/curl/pull/5896).
- Loading a huge preload file is probably not too interesting to most people,
- but using a custom file and reacting to HSTS response header probably are
- good features.
-
-DNS-over-TLS
-------------
-
- Similar to DNS-over-HTTPS. Could share quite a lot of generic code.
-
-ESNI (Encrypted SNI)
---------------------
+ECH (Encrypted Client Hello - formerly known as ESNI)
+-----------------------------------------------------
See Daniel's post on [Support of Encrypted
- SNI](https://curl.haxx.se/mail/lib-2019-03/0000.html) on the mailing list.
+ SNI](https://curl.se/mail/lib-2019-03/0000.html) on the mailing list.
Initial work exists in https://github.com/curl/curl/pull/4011
-
-thread-safe `curl_global_init()`
---------------------------------
-
- Fix the libcurl specific parts of the function to be thread-safe. Make sure
- it can be thread-safe if built with thread-safe 3rd party libraries.
- (probably can't include `curl_global_init_mem()` for obvious reasons)
-
-Hardcode “localhost”
---------------------
-
- No need to resolve it. Avoid a risk where this is resolved over the network
- and actually responds with something else than a local address. Some
- operating systems already do this. Also:
- https://tools.ietf.org/html/draft-ietf-dnsop-let-localhost-be-localhost-02
diff --git a/docs/SECURITY-PROCESS.md b/docs/SECURITY-PROCESS.md
index d2ac1fd84..a5d487adf 100644
--- a/docs/SECURITY-PROCESS.md
+++ b/docs/SECURITY-PROCESS.md
@@ -8,7 +8,7 @@ Publishing Information
----------------------
All known and public curl or libcurl related vulnerabilities are listed on
-[the curl website security page](https://curl.haxx.se/docs/security.html).
+[the curl website security page](https://curl.se/docs/security.html).
Security vulnerabilities **should not** be entered in the project's public bug
tracker.
@@ -125,8 +125,16 @@ Publishing Security Advisories
6. On security advisory release day, push the changes on the curl-www
repository's remote master branch.
+Hackerone
+---------
+
+Request the issue to be disclosed. If there are sensitive details present in
+the report and discussion, those should be redacted from the disclosure. The
+default policy is to disclose as much as possible as soon as the vulnerability
+has been published.
+
Bug Bounty
----------
-See [BUG-BOUNTY](https://curl.haxx.se/docs/bugbounty.html) for details on the
+See [BUG-BOUNTY](https://curl.se/docs/bugbounty.html) for details on the
bug bounty program.
diff --git a/docs/SSL-PROBLEMS.md b/docs/SSL-PROBLEMS.md
index 35000cf76..cd17cd615 100644
--- a/docs/SSL-PROBLEMS.md
+++ b/docs/SSL-PROBLEMS.md
@@ -84,4 +84,4 @@
References:
- https://curl.haxx.se/docs/ssl-compared.html
+ https://curl.se/docs/ssl-compared.html
diff --git a/docs/SSLCERTS.md b/docs/SSLCERTS.md
index 39170d085..415b540ad 100644
--- a/docs/SSLCERTS.md
+++ b/docs/SSLCERTS.md
@@ -60,8 +60,8 @@ server, do one of the following:
With the curl command line tool: --cacert [file]
3. Add the CA cert for your server to the existing default CA certificate
- store. The default CA certificate store can changed at compile time with the
- following configure options:
+ store. The default CA certificate store can be changed at compile time with
+ the following configure options:
--with-ca-bundle=FILE: use the specified file as CA certificate store. CA
certificates need to be concatenated in PEM format into this file.
@@ -119,7 +119,7 @@ server, do one of the following:
5. Get a better/different/newer CA cert bundle! One option is to extract the
one a recent Firefox browser uses by running 'make ca-bundle' in the curl
build tree root, or possibly download a version that was generated this
- way for you: [CA Extract](https://curl.haxx.se/docs/caextract.html)
+ way for you: [CA Extract](https://curl.se/docs/caextract.html)
Neglecting to use one of the above methods when dealing with a server using a
certificate that isn't signed by one of the certificates in the installed CA
diff --git a/docs/THANKS b/docs/THANKS
index ccec12146..fcac1f5f3 100644
--- a/docs/THANKS
+++ b/docs/THANKS
@@ -116,6 +116,7 @@ Andre Heinecke
Andreas Damm
Andreas Falkenhahn
Andreas Farber
+Andreas Fischer
Andreas Kostyrka
Andreas Malzahn
Andreas Ntaflos
@@ -135,6 +136,7 @@ Andrei Sedoi
Andrei Valeriu BICA
Andrei Virtosu
Andrej E Baranov
+Andrew Barnes
Andrew Benham
Andrew Biggs
Andrew Bushnell
@@ -158,7 +160,9 @@ Andy Fiddaman
Andy Serpa
Andy Tsouladze
Angus Mackay
+anio on github
anshnd on github
+Antarpreet Singh
Anthon Pang
Anthony Avina
Anthony Bryan
@@ -198,6 +202,7 @@ Austin Green
Avery Fay
Axel Tillequin
Ayoub Boudhar
+b9a1 on github
Balaji Parasuram
Balaji S Rao
Balaji Salunke
@@ -213,6 +218,7 @@ Bastien Bouclet
Basuke Suzuki
baumanj on github
bdry on github
+beckenc on github
Ben Boeckel
Ben Darnell
Ben Greear
@@ -343,6 +349,7 @@ Chris Flerackers
Chris Gaukroger
Chris Maltby
Chris Mumford
+Chris Paulson-Ellis
Chris Roberts
Chris Smowton
Chris Young
@@ -383,6 +390,7 @@ cmfrolick on github
codesniffer13 on github
Cody Jones
Cody Mack
+COFFEETALES on github
coinhubs on github
Colby Ranger
Colin Blair
@@ -401,6 +409,7 @@ Craig Markwardt
crazydef on github
Cris Bailiff
Cristian Greco
+Cristian Morales Vega
Cristian Rodríguez
Curt Bogmine
Cynthia Coan
@@ -409,6 +418,7 @@ Cyrill Osterwalder
Cédric Connes
Cédric Deltheil
D. Flinkmann
+d4d on hackerone
d912e3 on github
Da-Yoon Chung
daboul on github
@@ -426,6 +436,7 @@ Dan Donahue
Dan Fandrich
Dan Jacobson
Dan Johnson
+Dan Kenigsberg
Dan Locks
Dan McNulty
Dan Nelson
@@ -525,6 +536,7 @@ Dheeraj Sangamkar
Didier Brisebourg
Diego Bes
Diego Casorran
+Dietmar Hauser
Dilyan Palauzov
Dima Barsky
Dima Pasechnik
@@ -538,7 +550,9 @@ Dinar
Dirk Eddelbuettel
Dirk Feytons
Dirk Manske
+Dirk Wetter
Dirkjan Bussink
+Diven Qi
divinity76 on github
dkjjr89 on github
dkwolfe4 on github
@@ -578,6 +592,7 @@ Drake Arconis
dtmsecurity on github
Duane Cathey
Duncan Mac-Vicar Prett
+Duncan Wilcox
Dustin Boswell
Dusty Mabe
Duy Phan Thanh
@@ -611,6 +626,7 @@ Elliot Saba
Ellis Pritchard
Elmira A Semenova
elsamuko on github
+emanruse on github
Emanuele Bovisio
Emil Engler
Emil Lerner
@@ -709,8 +725,10 @@ Fred Noz
Fred Stluka
Frederic Lepied
Frederik B
+Frederik Wedel-Heinen
Fredrik Thulin
FuccDucc on github
+fullincome on github
Gabriel Kuri
Gabriel Sjoberg
Garrett Holmstrom
@@ -822,12 +840,14 @@ Hongli Lai
Howard Blaise
Howard Chu
hsiao yi
+htasta on github
Hubert Kario
Hugo van Kemenade
Huzaifa Sidhpurwala
huzunhao on github
hydra3333 on github
Hzhijun
+iammrtau on github
Ian D Allen
Ian Fette
Ian Ford
@@ -854,6 +874,7 @@ infinnovation-dev on github
Ingmar Runge
Ingo Ralf Blum
Ingo Wilken
+Ionuț-Francisc Oancea
Irfan Adilovic
Ironbars13 on github
Irving Wolfe
@@ -869,6 +890,7 @@ Jack Zhang
Jackarain on github
Jacky Lam
Jacob Barthelmeh
+Jacob Hoffman-Andrews
Jacob Meuser
Jacob Moshenko
Jactry Zeng
@@ -920,6 +942,7 @@ Jason S. Priebe
Javier Barroso
Javier Blazquez
Javier G. Sogo
+Javier Navarro
Javier Sixto
Jay Austin
Jayesh A Shah
@@ -979,6 +1002,7 @@ Jiri Dvorak
Jiri Hruska
Jiri Jaburek
Jiří Malák
+jmdavitt on github
jnbr on github
Jocelyn Jaubert
Joe Halpin
@@ -1065,6 +1089,7 @@ Joshua Kwan
Joshua Swink
Josie Huddleston
Josue Andrade Gomes
+José Joaquín Atria
Jozef Kralik
JP Mens
Juan Barreto
@@ -1101,6 +1126,7 @@ Jörg Mueller-Tolk
Jörn Hartroth
K. R. Walker
ka7 on github
+Kael1117 on github
Kai Engert
Kai Noda
Kai Sommerfeld
@@ -1144,6 +1170,7 @@ Kimmo Kinnunen
Kirill Marchuk
Kjell Ericson
Kjetil Jacobsen
+Klaus Crusius
Klaus Stein
Klevtsov Vadim
Kobi Gurkan
@@ -1152,6 +1179,7 @@ Konstantin Isakov
Konstantin Kushnir
kotoriのねこ
kouzhudong on github
+Kovalkov Dmitrii
kreshano on github
Kris Kennaway
Krishnendu Majumdar
@@ -1161,6 +1189,7 @@ Kristian Köhntopp
Kristian Mide
Kristiyan Tsaklev
Kristoffer Gleditsch
+Kunal Chandarana
Kunal Ekawde
Kurt Fankhauser
Kwon-Young Choi
@@ -1249,6 +1278,7 @@ Luz Paz
Luật Nguyễn
Lyman Epp
Lyndon Hill
+M.R.T on github
Maciej Karpiuk
Maciej Puzio
Maciej W. Rozycki
@@ -1316,6 +1346,7 @@ Maros Priputen
Marquis de Muesli
Martijn Koster
Martin Ankerl
+Martin Bašti
Martin C. Martin
Martin Drasar
Martin Dreher
@@ -1386,6 +1417,7 @@ Melissa Mears
Mert Yazıcıoğlu
Mettgut Jamalla
Michael Anti
+Michael Baentsch
Michael Benedict
Michael Brehm
Michael Calmer
@@ -1407,6 +1439,8 @@ Michael Lee
Michael Maltese
Michael Mealling
Michael Mueller
+Michael Musset
+Michael Olbrich
Michael Osipov
Michael Schmid
Michael Smith
@@ -1451,6 +1485,7 @@ Mike Revi
Miklos Nemeth
Miloš Ljumović
Mingliang Zhu
+Mingtao Yang
Miroslav Franc
Miroslav Spousta
Mischa Salle
@@ -1524,6 +1559,7 @@ Nikos Tsipinakis
niner on github
Ning Dong
Nir Soffer
+Niranjan Hasabnis
Nis Jorgensen
nk
NobodyXu on github
@@ -1533,6 +1569,7 @@ nopjmp on github
Norbert Frese
Norbert Kett
Norbert Novotny
+nosajsnikta on github
NTMan on Github
Octavio Schroeder
Ofer
@@ -1548,6 +1585,7 @@ Oliver Gondža
Oliver Graute
Oliver Kuckertz
Oliver Schindler
+Oliver Urbann
Olivier Berger
Olivier Brunel
Omar Ramadan
@@ -1624,6 +1662,7 @@ pendrek at hackerone
Peng Li
Per Lundberg
Per Malmberg
+Per Nilsson
Pete Lomax
Peter Bray
Peter Forret
@@ -1632,6 +1671,7 @@ Peter Gal
Peter Heuchert
Peter Hjalmarsson
Peter Korsgaard
+Peter Körner
Peter Lamare
Peter Lamberg
Peter Laser
@@ -1663,6 +1703,7 @@ Philip Craig
Philip Gladstone
Philip Langdale
Philip Prindeville
+Philipp Klaus Krause
Philipp Waehnert
Philippe Hameau
Philippe Marguinaud
@@ -1690,6 +1731,7 @@ Puneet Pawaia
qiandu2006 on github
Quagmire
Quanah Gibson-Mount
+Quentin Balland
Quinn Slack
R. Dennis Steed
Radoslav Georgiev
@@ -1721,6 +1763,7 @@ Ray Dassen
Ray Pekowski
Ray Satiro
Razvan Cojocaru
+rcombs on github
Reed Loden
Reinhard Max
Reinout van Schouwen
@@ -1796,6 +1839,7 @@ Robert Schumann
Robert Weaver
Robert Wruck
Robin Cornelius
+Robin Douine
Robin Johnson
Robin Kay
Robson Braga Araujo
@@ -1826,6 +1870,7 @@ Rosimildo da Silva
Ross Burton
Roy Bellingan
Roy Shan
+Rui LIU
Rune Kleveland
Ruslan Baratov
Ruslan Gazizov
@@ -1849,12 +1894,14 @@ Sam Deane
Sam Hurst
Sam Roth
Sam Schanken
+Samanta Navarro
Sampo Kellomaki
Samuel Díaz García
Samuel Listopad
Samuel Marks
Samuel Surtees
Samuel Thibault
+Samuel Tranchet
Sander Gates
Sandor Feldi
Santhana Todatry
@@ -1924,6 +1971,7 @@ Siva Sivaraman
SLDiggie on github
smuellerDD on github
sn on hackerone
+sofaboss on github
Somnath Kundu
Song Ma
Sonia Subramanian
@@ -1947,6 +1995,7 @@ Stefan Grether
Stefan Kanthak
Stefan Krause
Stefan Neis
+Stefan Strogin
Stefan Teleman
Stefan Tomanek
Stefan Ulrich
@@ -2022,6 +2071,7 @@ therealhirudo on github
tholin on github
Thomas Bouzerar
Thomas Braun
+Thomas Danielsson
Thomas Gamper
Thomas Glanzmann
Thomas J. Moore
@@ -2076,6 +2126,7 @@ Todd Short
Todd Vierling
Tom Benoist
Tom Donovan
+Tom G. Christensen
Tom Grace
Tom Greenslade
Tom Lee
@@ -2133,6 +2184,7 @@ Valentin David
Valentyn Korniienko
Valerii Zapodovnikov
vanillajonathan on github
+Varnavas Papaioannou
Vasiliy Faronov
Vasily Lobaskin
Vasy Okhin
@@ -2200,6 +2252,7 @@ Xiang Xiao
Xiangbin Li
Xiaoyin Liu
XmiliaH on github
+xnynx on github
xwxbug on github
Yaakov Selkowitz
Yang Tse
diff --git a/docs/THANKS-filter b/docs/THANKS-filter
index e11ad6d27..eb1f653fa 100644
--- a/docs/THANKS-filter
+++ b/docs/THANKS-filter
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -122,3 +122,4 @@ s/Yamada Yasuharu/Yasuharu Yamada/
s/Jim Gallagher/James Gallagher/
s/Steve Brokenshire/Stephen Brokenshire/
s/wangp on github/Peter Wang/
+s# *autobuild https://.*##
diff --git a/docs/TODO b/docs/TODO
index bd9b0e883..d064ca28c 100644
--- a/docs/TODO
+++ b/docs/TODO
@@ -52,6 +52,8 @@
2.4 Split connect and authentication process
2.5 Edge-triggered sockets should work
2.6 multi upkeep
+ 2.7 Virtual external sockets
+ 2.8 dynamically decide to use socketpair
3. Documentation
3.2 Provide cmake config-file
@@ -135,6 +137,7 @@
17.2 Handle growing SFTP files
17.3 Support better than MD5 hostkey hash
17.4 Support CURLOPT_PREQUOTE
+ 17.5 SSH over HTTPS proxy with more backends
18. Command line tool
18.1 sync
@@ -158,13 +161,13 @@
18.19 expand ~/ in config files
18.20 host name sections in config files
18.21 retry on the redirected-to URL
- 18.22 Add flag to specify download directory
18.23 Set the modification date on an uploaded file
18.24 Use multiple parallel transfers for a single download
19. Build
19.1 roffit
19.2 Enable PIE and RELRO by default
+ 19.3 Don't use GNU libtool on OpenBSD
20. Test suite
20.1 SSL tunnel
@@ -238,6 +241,8 @@
This could be used by curl on macOS when built without a separate IDN library
and an IDN host name is used in a URL.
+ See initial work in https://github.com/curl/curl/pull/5371
+
1.7 Support HTTP/2 for HTTP(S) proxies
Support for doing HTTP/2 to HTTP and HTTPS proxies is still missing.
@@ -410,7 +415,7 @@
See https://github.com/curl/curl/issues/3523
Michael Kaufmann suggestion here:
- https://curl.haxx.se/video/curlup-2017/2017-03-19_05_Michael_Kaufmann_Websocket_support_for_curl.mp4
+ https://curl.se/video/curlup-2017/2017-03-19_05_Michael_Kaufmann_Websocket_support_for_curl.mp4
1.30 config file parsing
@@ -481,6 +486,23 @@
See https://github.com/curl/curl/issues/3199
+2.7 Virtual external sockets
+
+ libcurl performs operations on the given file descriptor that presumes it is
+ a socket and an application cannot replace them at the moment. Allowing an
+ application to fully replace those would allow a larger degree of freedom and
+ flexibility.
+
+ See https://github.com/curl/curl/issues/5835
+
+2.8 dynamically decide to use socketpair
+
+ For users who don't use curl_multi_wait() or don't care for
+ curl_multi_wakeup(), we could introduce a way to make libcurl NOT
+ create a socketpair in the multi handle.
+
+ See https://github.com/curl/curl/issues/4829
+
3. Documentation
3.2 Provide cmake config-file
@@ -503,7 +525,7 @@
When trying to connect passively to a server which only supports active
connections, libcurl returns CURLE_FTP_WEIRD_PASV_REPLY and closes the
connection. There could be a way to fallback to an active connection (and
- vice versa). https://curl.haxx.se/bug/feature.cgi?id=1754793
+ vice versa). https://curl.se/bug/feature.cgi?id=1754793
4.3 Earlier bad letter detection
@@ -540,7 +562,7 @@
5.1 Better persistency for HTTP 1.0
"Better" support for persistent connections over HTTP 1.0
- https://curl.haxx.se/bug/feature.cgi?id=1089001
+ https://curl.se/bug/feature.cgi?id=1089001
5.2 Set custom client ip when using haproxy protocol
@@ -617,7 +639,7 @@
hack ;-)
Please see the following thread for more information:
- https://curl.haxx.se/mail/lib-2012-05/0178.html
+ https://curl.se/mail/lib-2012-05/0178.html
8. POP3
@@ -744,9 +766,9 @@ that doesn't exist on the server, just like --ftp-create-dirs.
https://www.rfc-editor.org/rfc/rfc6698.txt
An initial patch was posted by Suresh Krishnaswamy on March 7th 2013
- (https://curl.haxx.se/mail/lib-2013-03/0075.html) but it was a too simple
+ (https://curl.se/mail/lib-2013-03/0075.html) but it was a too simple
approach. See Daniel's comments:
- https://curl.haxx.se/mail/lib-2013-03/0103.html . libunbound may be the
+ https://curl.se/mail/lib-2013-03/0103.html . libunbound may be the
correct library to base this development on.
Björn Stenberg wrote a separate initial take on DANE that was never
@@ -910,6 +932,13 @@ that doesn't exist on the server, just like --ftp-create-dirs.
The two other QUOTE options are supported for SFTP, but this was left out for
unknown reasons!
+17.5 SSH over HTTPS proxy with more backends
+
+ The SSH based protocols SFTP and SCP didn't work over HTTPS proxy at
+ all until PR https://github.com/curl/curl/pull/6021 brought the
+ functionality with the libssh2 backend. Presumably, this support
+ can/could be added for the other backends as well.
+
18. Command line tool
18.1 sync
@@ -1112,12 +1141,6 @@ that doesn't exist on the server, just like --ftp-create-dirs.
See https://github.com/curl/curl/issues/5462
-18.22 Add flag to specify download directory
-
- A directory name to basically prepend to the file name -O and -o use. Saves
- user from having to manually "cd" to the directory. Especially useful for
- command lines with multiple -O and different download directories.
-
18.23 Set the modification date on an uploaded file
For SFTP and posssibly FTP, curl could offer an option to set the
@@ -1165,6 +1188,15 @@ that doesn't exist on the server, just like --ftp-create-dirs.
to no impact, neither on the performance nor on the general functionality of
curl.
+19.3 Don't use GNU libtool on OpenBSD
+ When compiling curl on OpenBSD with "--enable-debug" it will give linking
+ errors when you use GNU libtool. This can be fixed by using the libtool
+ provided by OpenBSD itself. However for this the user always needs to invoke
+ make with "LIBTOOL=/usr/bin/libtool". It would be nice if the script could
+ have some magic to detect if this system is an OpenBSD host and then use the
+ OpenBSD libtool instead.
+
+ See https://github.com/curl/curl/issues/5862
20. Test suite
diff --git a/docs/TheArtOfHttpScripting b/docs/TheArtOfHttpScripting
deleted file mode 100644
index 65bda6255..000000000
--- a/docs/TheArtOfHttpScripting
+++ /dev/null
@@ -1,758 +0,0 @@
- _ _ ____ _
- ___| | | | _ \| |
- / __| | | | |_) | |
- | (__| |_| | _ <| |___
- \___|\___/|_| \_\_____|
-
-
-The Art Of Scripting HTTP Requests Using Curl
-
- 1. HTTP Scripting
- 1.1 Background
- 1.2 The HTTP Protocol
- 1.3 See the Protocol
- 1.4 See the Timing
- 1.5 See the Response
- 2. URL
- 2.1 Spec
- 2.2 Host
- 2.3 Port number
- 2.4 User name and password
- 2.5 Path part
- 3. Fetch a page
- 3.1 GET
- 3.2 HEAD
- 3.3 Multiple URLs in a single command line
- 3.4 Multiple HTTP methods in a single command line
- 4. HTML forms
- 4.1 Forms explained
- 4.2 GET
- 4.3 POST
- 4.4 File Upload POST
- 4.5 Hidden Fields
- 4.6 Figure Out What A POST Looks Like
- 5. HTTP upload
- 5.1 PUT
- 6. HTTP Authentication
- 6.1 Basic Authentication
- 6.2 Other Authentication
- 6.3 Proxy Authentication
- 6.4 Hiding credentials
- 7. More HTTP Headers
- 7.1 Referer
- 7.2 User Agent
- 8. Redirects
- 8.1 Location header
- 8.2 Other redirects
- 9. Cookies
- 9.1 Cookie Basics
- 9.2 Cookie options
- 10. HTTPS
- 10.1 HTTPS is HTTP secure
- 10.2 Certificates
- 11. Custom Request Elements
- 11.1 Modify method and headers
- 11.2 More on changed methods
- 12. Web Login
- 12.1 Some login tricks
- 13. Debug
- 13.1 Some debug tricks
- 14. References
- 14.1 Standards
- 14.2 Sites
-
-==============================================================================
-
-1. HTTP Scripting
-
- 1.1 Background
-
- This document assumes that you're familiar with HTML and general networking.
-
- The increasing amount of applications moving to the web has made "HTTP
- Scripting" more frequently requested and wanted. To be able to automatically
- extract information from the web, to fake users, to post or upload data to
- web servers are all important tasks today.
-
- Curl is a command line tool for doing all sorts of URL manipulations and
- transfers, but this particular document will focus on how to use it when
- doing HTTP requests for fun and profit. I'll assume that you know how to
- invoke 'curl --help' or 'curl --manual' to get basic information about it.
-
- Curl is not written to do everything for you. It makes the requests, it gets
- the data, it sends data and it retrieves the information. You probably need
- to glue everything together using some kind of script language or repeated
- manual invokes.
-
- 1.2 The HTTP Protocol
-
- HTTP is the protocol used to fetch data from web servers. It is a very simple
- protocol that is built upon TCP/IP. The protocol also allows information to
- get sent to the server from the client using a few different methods, as will
- be shown here.
-
- HTTP is plain ASCII text lines being sent by the client to a server to
- request a particular action, and then the server replies a few text lines
- before the actual requested content is sent to the client.
-
- The client, curl, sends a HTTP request. The request contains a method (like
- GET, POST, HEAD etc), a number of request headers and sometimes a request
- body. The HTTP server responds with a status line (indicating if things went
- well), response headers and most often also a response body. The "body" part
- is the plain data you requested, like the actual HTML or the image etc.
-
- 1.3 See the Protocol
-
- Using curl's option --verbose (-v as a short option) will display what kind
- of commands curl sends to the server, as well as a few other informational
- texts.
-
- --verbose is the single most useful option when it comes to debug or even
- understand the curl<->server interaction.
-
- Sometimes even --verbose is not enough. Then --trace and --trace-ascii offer
- even more details as they show EVERYTHING curl sends and receives. Use it
- like this:
-
- curl --trace-ascii debugdump.txt http://www.example.com/
-
- 1.4 See the Timing
-
- Many times you may wonder what exactly is taking all the time, or you just
- want to know the amount of milliseconds between two points in a
- transfer. For those, and other similar situations, the --trace-time option
- is what you need. It'll prepend the time to each trace output line:
-
- curl --trace-ascii d.txt --trace-time http://example.com/
-
- 1.5 See the Response
-
- By default curl sends the response to stdout. You need to redirect it
- somewhere to avoid that, most often that is done with -o or -O.
-
-2. URL
-
- 2.1 Spec
-
- The Uniform Resource Locator format is how you specify the address of a
- particular resource on the Internet. You know these, you've seen URLs like
- https://curl.haxx.se or https://yourbank.com a million times. RFC 3986 is the
- canonical spec. And yeah, the formal name is not URL, it is URI.
-
- 2.2 Host
-
- The host name is usually resolved using DNS or your /etc/hosts file to an IP
- address and that's what curl will communicate with. Alternatively you specify
- the IP address directly in the URL instead of a name.
-
- For development and other trying out situations, you can point to a different
- IP address for a host name than what would otherwise be used, by using curl's
- --resolve option:
-
- curl --resolve www.example.org:80:127.0.0.1 http://www.example.org/
-
- 2.3 Port number
-
- Each protocol curl supports operates on a default port number, be it over TCP
- or in some cases UDP. Normally you don't have to take that into
- consideration, but at times you run test servers on other ports or
- similar. Then you can specify the port number in the URL with a colon and a
- number immediately following the host name. Like when doing HTTP to port
- 1234:
-
- curl http://www.example.org:1234/
-
- The port number you specify in the URL is the number that the server uses to
- offer its services. Sometimes you may use a local proxy, and then you may
- need to specify that proxy's port number separately for what curl needs to
- connect to locally. Like when using a HTTP proxy on port 4321:
-
- curl --proxy http://proxy.example.org:4321 http://remote.example.org/
-
- 2.4 User name and password
-
- Some services are setup to require HTTP authentication and then you need to
- provide name and password which is then transferred to the remote site in
- various ways depending on the exact authentication protocol used.
-
- You can opt to either insert the user and password in the URL or you can
- provide them separately:
-
- curl http://user:password@example.org/
-
- or
-
- curl -u user:password http://example.org/
-
- You need to pay attention that this kind of HTTP authentication is not what
- is usually done and requested by user-oriented websites these days. They
- tend to use forms and cookies instead.
-
- 2.5 Path part
-
- The path part is just sent off to the server to request that it sends back
- the associated response. The path is what is to the right side of the slash
- that follows the host name and possibly port number.
-
-3. Fetch a page
-
- 3.1 GET
-
- The simplest and most common request/operation made using HTTP is to GET a
- URL. The URL could itself refer to a web page, an image or a file. The client
- issues a GET request to the server and receives the document it asked for.
- If you issue the command line
-
- curl https://curl.haxx.se
-
- you get a web page returned in your terminal window. The entire HTML document
- that that URL holds.
-
- All HTTP replies contain a set of response headers that are normally hidden,
- use curl's --include (-i) option to display them as well as the rest of the
- document.
-
- 3.2 HEAD
-
- You can ask the remote server for ONLY the headers by using the --head (-I)
- option which will make curl issue a HEAD request. In some special cases
- servers deny the HEAD method while others still work, which is a particular
- kind of annoyance.
-
- The HEAD method is defined and made so that the server returns the headers
- exactly the way it would do for a GET, but without a body. It means that you
- may see a Content-Length: in the response headers, but there must not be an
- actual body in the HEAD response.
-
- 3.3 Multiple URLs in a single command line
-
- A single curl command line may involve one or many URLs. The most common case
- is probably to just use one, but you can specify any amount of URLs. Yes
- any. No limits. You'll then get requests repeated over and over for all the
- given URLs.
-
- Example, send two GETs:
-
- curl http://url1.example.com http://url2.example.com
-
- If you use --data to POST to the URL, using multiple URLs means that you send
- that same POST to all the given URLs.
-
- Example, send two POSTs:
-
- curl --data name=curl http://url1.example.com http://url2.example.com
-
-
- 3.4 Multiple HTTP methods in a single command line
-
- Sometimes you need to operate on several URLs in a single command line and do
- different HTTP methods on each. For this, you'll enjoy the --next option. It
- is basically a separator that separates a bunch of options from the next. All
- the URLs before --next will get the same method and will get all the POST
- data merged into one.
-
- When curl reaches the --next on the command line, it'll sort of reset the
- method and the POST data and allow a new set.
-
- Perhaps this is best shown with a few examples. To send first a HEAD and then
- a GET:
-
- curl -I http://example.com --next http://example.com
-
- To first send a POST and then a GET:
-
- curl -d score=10 http://example.com/post.cgi --next http://example.com/results.html
-
-
-4. HTML forms
-
- 4.1 Forms explained
-
- Forms are the general way a website can present a HTML page with fields for
- the user to enter data in, and then press some kind of 'OK' or 'Submit'
- button to get that data sent to the server. The server then typically uses
- the posted data to decide how to act. Like using the entered words to search
- in a database, or to add the info in a bug tracking system, display the entered
- address on a map or using the info as a login-prompt verifying that the user
- is allowed to see what it is about to see.
-
- Of course there has to be some kind of program on the server end to receive
- the data you send. You cannot just invent something out of the air.
-
- 4.2 GET
-
- A GET-form uses the method GET, as specified in HTML like:
-
- <form method="GET" action="junk.cgi">
- <input type=text name="birthyear">
- <input type=submit name=press value="OK">
- </form>
-
- In your favorite browser, this form will appear with a text box to fill in
- and a press-button labeled "OK". If you fill in '1905' and press the OK
- button, your browser will then create a new URL to get for you. The URL will
- get "junk.cgi?birthyear=1905&press=OK" appended to the path part of the
- previous URL.
-
- If the original form was seen on the page "www.hotmail.com/when/birth.html",
- the second page you'll get will become
- "www.hotmail.com/when/junk.cgi?birthyear=1905&press=OK".
-
- Most search engines work this way.
-
- To make curl do the GET form post for you, just enter the expected created
- URL:
-
- curl "http://www.hotmail.com/when/junk.cgi?birthyear=1905&press=OK"
-
- 4.3 POST
-
- The GET method makes all input field names get displayed in the URL field of
- your browser. That's generally a good thing when you want to be able to
- bookmark that page with your given data, but it is an obvious disadvantage
- if you entered secret information in one of the fields or if there are a
- large amount of fields creating a very long and unreadable URL.
-
- The HTTP protocol then offers the POST method. This way the client sends the
- data separated from the URL and thus you won't see any of it in the URL
- address field.
-
- The form would look very similar to the previous one:
-
- <form method="POST" action="junk.cgi">
- <input type=text name="birthyear">
- <input type=submit name=press value=" OK ">
- </form>
-
- And to use curl to post this form with the same data filled in as before, we
- could do it like:
-
- curl --data "birthyear=1905&press=%20OK%20" \
- http://www.example.com/when.cgi
-
- This kind of POST will use the Content-Type
- application/x-www-form-urlencoded and is the most widely used POST kind.
-
- The data you send to the server MUST already be properly encoded, curl will
- not do that for you. For example, if you want the data to contain a space,
- you need to replace that space with %20 etc. Failing to comply with this
- will most likely cause your data to be received wrongly and messed up.
-
- Recent curl versions can in fact url-encode POST data for you, like this:
-
- curl --data-urlencode "name=I am Daniel" http://www.example.com
-
- If you repeat --data several times on the command line, curl will
- concatenate all the given data pieces - and put a '&' symbol between each
- data segment.
-
- 4.4 File Upload POST
-
- Back in late 1995 they defined an additional way to post data over HTTP. It
- is documented in the RFC 1867, why this method sometimes is referred to as
- RFC1867-posting.
-
- This method is mainly designed to better support file uploads. A form that
- allows a user to upload a file could be written like this in HTML:
-
- <form method="POST" enctype='multipart/form-data' action="upload.cgi">
- <input type=file name=upload>
- <input type=submit name=press value="OK">
- </form>
-
- This clearly shows that the Content-Type about to be sent is
- multipart/form-data.
-
- To post to a form like this with curl, you enter a command line like:
-
- curl --form upload=@localfilename --form press=OK [URL]
-
- 4.5 Hidden Fields
-
- A very common way for HTML based applications to pass state information
- between pages is to add hidden fields to the forms. Hidden fields are
- already filled in, they aren't displayed to the user and they get passed
- along just as all the other fields.
-
- A similar example form with one visible field, one hidden field and one
- submit button could look like:
-
- <form method="POST" action="foobar.cgi">
- <input type=text name="birthyear">
- <input type=hidden name="person" value="daniel">
- <input type=submit name="press" value="OK">
- </form>
-
- To POST this with curl, you won't have to think about if the fields are
- hidden or not. To curl they're all the same:
-
- curl --data "birthyear=1905&press=OK&person=daniel" [URL]
-
- 4.6 Figure Out What A POST Looks Like
-
- When you're about fill in a form and send to a server by using curl instead
- of a browser, you're of course very interested in sending a POST exactly the
- way your browser does.
-
- An easy way to get to see this, is to save the HTML page with the form on
- your local disk, modify the 'method' to a GET, and press the submit button
- (you could also change the action URL if you want to).
-
- You will then clearly see the data get appended to the URL, separated with a
- '?'-letter as GET forms are supposed to.
-
-5. HTTP upload
-
- 5.1 PUT
-
- Perhaps the best way to upload data to a HTTP server is to use PUT. Then
- again, this of course requires that someone put a program or script on the
- server end that knows how to receive a HTTP PUT stream.
-
- Put a file to a HTTP server with curl:
-
- curl --upload-file uploadfile http://www.example.com/receive.cgi
-
-6. HTTP Authentication
-
- 6.1 Basic Authentication
-
- HTTP Authentication is the ability to tell the server your username and
- password so that it can verify that you're allowed to do the request you're
- doing. The Basic authentication used in HTTP (which is the type curl uses by
- default) is *plain* *text* based, which means it sends username and password
- only slightly obfuscated, but still fully readable by anyone that sniffs on
- the network between you and the remote server.
-
- To tell curl to use a user and password for authentication:
-
- curl --user name:password http://www.example.com
-
- 6.2 Other Authentication
-
- The site might require a different authentication method (check the headers
- returned by the server), and then --ntlm, --digest, --negotiate or even
- --anyauth might be options that suit you.
-
- 6.3 Proxy Authentication
-
- Sometimes your HTTP access is only available through the use of a HTTP
- proxy. This seems to be especially common at various companies. A HTTP proxy
- may require its own user and password to allow the client to get through to
- the Internet. To specify those with curl, run something like:
-
- curl --proxy-user proxyuser:proxypassword curl.haxx.se
-
- If your proxy requires the authentication to be done using the NTLM method,
- use --proxy-ntlm, if it requires Digest use --proxy-digest.
-
- If you use any one of these user+password options but leave out the password
- part, curl will prompt for the password interactively.
-
- 6.4 Hiding credentials
-
- Do note that when a program is run, its parameters might be possible to see
- when listing the running processes of the system. Thus, other users may be
- able to watch your passwords if you pass them as plain command line
- options. There are ways to circumvent this.
-
- It is worth noting that while this is how HTTP Authentication works, very
- many websites will not use this concept when they provide logins etc. See
- the Web Login chapter further below for more details on that.
-
-7. More HTTP Headers
-
- 7.1 Referer
-
- A HTTP request may include a 'referer' field (yes it is misspelled), which
- can be used to tell from which URL the client got to this particular
- resource. Some programs/scripts check the referer field of requests to verify
- that this wasn't arriving from an external site or an unknown page. While
- this is a stupid way to check something so easily forged, many scripts still
- do it. Using curl, you can put anything you want in the referer-field and
- thus more easily be able to fool the server into serving your request.
-
- Use curl to set the referer field with:
-
- curl --referer http://www.example.come http://www.example.com
-
- 7.2 User Agent
-
- Very similar to the referer field, all HTTP requests may set the User-Agent
- field. It names what user agent (client) that is being used. Many
- applications use this information to decide how to display pages. Silly web
- programmers try to make different pages for users of different browsers to
- make them look the best possible for their particular browsers. They usually
- also do different kinds of javascript, vbscript etc.
-
- At times, you will see that getting a page with curl will not return the same
- page that you see when getting the page with your browser. Then you know it
- is time to set the User Agent field to fool the server into thinking you're
- one of those browsers.
-
- To make curl look like Internet Explorer 5 on a Windows 2000 box:
-
- curl --user-agent "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)" [URL]
-
- Or why not look like you're using Netscape 4.73 on an old Linux box:
-
- curl --user-agent "Mozilla/4.73 [en] (X11; U; Linux 2.2.15 i686)" [URL]
-
-8. Redirects
-
- 8.1 Location header
-
- When a resource is requested from a server, the reply from the server may
- include a hint about where the browser should go next to find this page, or a
- new page keeping newly generated output. The header that tells the browser
- to redirect is Location:.
-
- Curl does not follow Location: headers by default, but will simply display
- such pages in the same manner it displays all HTTP replies. It does however
- feature an option that will make it attempt to follow the Location: pointers.
-
- To tell curl to follow a Location:
-
- curl --location http://www.example.com
-
- If you use curl to POST to a site that immediately redirects you to another
- page, you can safely use --location (-L) and --data/--form together. Curl will
- only use POST in the first request, and then revert to GET in the following
- operations.
-
- 8.2 Other redirects
-
- Browser typically support at least two other ways of redirects that curl
- doesn't: first the html may contain a meta refresh tag that asks the browser
- to load a specific URL after a set number of seconds, or it may use
- javascript to do it.
-
-9. Cookies
-
- 9.1 Cookie Basics
-
- The way the web browsers do "client side state control" is by using
- cookies. Cookies are just names with associated contents. The cookies are
- sent to the client by the server. The server tells the client for what path
- and host name it wants the cookie sent back, and it also sends an expiration
- date and a few more properties.
-
- When a client communicates with a server with a name and path as previously
- specified in a received cookie, the client sends back the cookies and their
- contents to the server, unless of course they are expired.
-
- Many applications and servers use this method to connect a series of requests
- into a single logical session. To be able to use curl in such occasions, we
- must be able to record and send back cookies the way the web application
- expects them. The same way browsers deal with them.
-
- 9.2 Cookie options
-
- The simplest way to send a few cookies to the server when getting a page with
- curl is to add them on the command line like:
-
- curl --cookie "name=Daniel" http://www.example.com
-
- Cookies are sent as common HTTP headers. This is practical as it allows curl
- to record cookies simply by recording headers. Record cookies with curl by
- using the --dump-header (-D) option like:
-
- curl --dump-header headers_and_cookies http://www.example.com
-
- (Take note that the --cookie-jar option described below is a better way to
- store cookies.)
-
- Curl has a full blown cookie parsing engine built-in that comes in use if you
- want to reconnect to a server and use cookies that were stored from a
- previous connection (or hand-crafted manually to fool the server into
- believing you had a previous connection). To use previously stored cookies,
- you run curl like:
-
- curl --cookie stored_cookies_in_file http://www.example.com
-
- Curl's "cookie engine" gets enabled when you use the --cookie option. If you
- only want curl to understand received cookies, use --cookie with a file that
- doesn't exist. Example, if you want to let curl understand cookies from a
- page and follow a location (and thus possibly send back cookies it received),
- you can invoke it like:
-
- curl --cookie nada --location http://www.example.com
-
- Curl has the ability to read and write cookie files that use the same file
- format that Netscape and Mozilla once used. It is a convenient way to share
- cookies between scripts or invokes. The --cookie (-b) switch automatically
- detects if a given file is such a cookie file and parses it, and by using the
- --cookie-jar (-c) option you'll make curl write a new cookie file at the end
- of an operation:
-
- curl --cookie cookies.txt --cookie-jar newcookies.txt \
- http://www.example.com
-
-10. HTTPS
-
- 10.1 HTTPS is HTTP secure
-
- There are a few ways to do secure HTTP transfers. By far the most common
- protocol for doing this is what is generally known as HTTPS, HTTP over
- SSL. SSL encrypts all the data that is sent and received over the network and
- thus makes it harder for attackers to spy on sensitive information.
-
- SSL (or TLS as the latest version of the standard is called) offers a
- truckload of advanced features to allow all those encryptions and key
- infrastructure mechanisms encrypted HTTP requires.
-
- Curl supports encrypted fetches when built to use a TLS library and it can be
- built to use one out of a fairly large set of libraries - "curl -V" will show
- which one your curl was built to use (if any!). To get a page from a HTTPS
- server, simply run curl like:
-
- curl https://secure.example.com
-
- 10.2 Certificates
-
- In the HTTPS world, you use certificates to validate that you are the one
- you claim to be, as an addition to normal passwords. Curl supports client-
- side certificates. All certificates are locked with a pass phrase, which you
- need to enter before the certificate can be used by curl. The pass phrase
- can be specified on the command line or if not, entered interactively when
- curl queries for it. Use a certificate with curl on a HTTPS server like:
-
- curl --cert mycert.pem https://secure.example.com
-
- curl also tries to verify that the server is who it claims to be, by
- verifying the server's certificate against a locally stored CA cert
- bundle. Failing the verification will cause curl to deny the connection. You
- must then use --insecure (-k) in case you want to tell curl to ignore that
- the server can't be verified.
-
- More about server certificate verification and ca cert bundles can be read
- in the SSLCERTS document, available online here:
-
- https://curl.haxx.se/docs/sslcerts.html
-
- At times you may end up with your own CA cert store and then you can tell
- curl to use that to verify the server's certificate:
-
- curl --cacert ca-bundle.pem https://example.com/
-
-
-11. Custom Request Elements
-
-11.1 Modify method and headers
-
- Doing fancy stuff, you may need to add or change elements of a single curl
- request.
-
- For example, you can change the POST request to a PROPFIND and send the data
- as "Content-Type: text/xml" (instead of the default Content-Type) like this:
-
- curl --data "<xml>" --header "Content-Type: text/xml" \
- --request PROPFIND url.com
-
- You can delete a default header by providing one without content. Like you
- can ruin the request by chopping off the Host: header:
-
- curl --header "Host:" http://www.example.com
-
- You can add headers the same way. Your server may want a "Destination:"
- header, and you can add it:
-
- curl --header "Destination: http://nowhere" http://example.com
-
- 11.2 More on changed methods
-
- It should be noted that curl selects which methods to use on its own
- depending on what action to ask for. -d will do POST, -I will do HEAD and so
- on. If you use the --request / -X option you can change the method keyword
- curl selects, but you will not modify curl's behavior. This means that if you
- for example use -d "data" to do a POST, you can modify the method to a
- PROPFIND with -X and curl will still think it sends a POST. You can change
- the normal GET to a POST method by simply adding -X POST in a command line
- like:
-
- curl -X POST http://example.org/
-
- ... but curl will still think and act as if it sent a GET so it won't send any
- request body etc.
-
-
-12. Web Login
-
- 12.1 Some login tricks
-
- While not strictly just HTTP related, it still causes a lot of people problems
- so here's the executive run-down of how the vast majority of all login forms
- work and how to login to them using curl.
-
- It can also be noted that to do this properly in an automated fashion, you
- will most certainly need to script things and do multiple curl invokes etc.
-
- First, servers mostly use cookies to track the logged-in status of the
- client, so you will need to capture the cookies you receive in the
- responses. Then, many sites also set a special cookie on the login page (to
- make sure you got there through their login page) so you should make a habit
- of first getting the login-form page to capture the cookies set there.
-
- Some web-based login systems feature various amounts of javascript, and
- sometimes they use such code to set or modify cookie contents. Possibly they
- do that to prevent programmed logins, like this manual describes how to...
- Anyway, if reading the code isn't enough to let you repeat the behavior
- manually, capturing the HTTP requests done by your browsers and analyzing the
- sent cookies is usually a working method to work out how to shortcut the
- javascript need.
-
- In the actual <form> tag for the login, lots of sites fill-in random/session
- or otherwise secretly generated hidden tags and you may need to first capture
- the HTML code for the login form and extract all the hidden fields to be able
- to do a proper login POST. Remember that the contents need to be URL encoded
- when sent in a normal POST.
-
-13. Debug
-
- 13.1 Some debug tricks
-
- Many times when you run curl on a site, you'll notice that the site doesn't
- seem to respond the same way to your curl requests as it does to your
- browser's.
-
- Then you need to start making your curl requests more similar to your
- browser's requests:
-
- * Use the --trace-ascii option to store fully detailed logs of the requests
- for easier analyzing and better understanding
-
- * Make sure you check for and use cookies when needed (both reading with
- --cookie and writing with --cookie-jar)
-
- * Set user-agent to one like a recent popular browser does
-
- * Set referer like it is set by the browser
-
- * If you use POST, make sure you send all the fields and in the same order as
- the browser does it.
-
- A very good helper to make sure you do this right, is the LiveHTTPHeader tool
- that lets you view all headers you send and receive with Mozilla/Firefox
- (even when using HTTPS). Chrome features similar functionality out of the box
- among the developer's tools.
-
- A more raw approach is to capture the HTTP traffic on the network with tools
- such as ethereal or tcpdump and check what headers that were sent and
- received by the browser. (HTTPS makes this technique inefficient.)
-
-14. References
-
- 14.1 Standards
-
- RFC 7230 is a must to read if you want in-depth understanding of the HTTP
- protocol
-
- RFC 3986 explains the URL syntax
-
- RFC 1867 defines the HTTP post upload format
-
- RFC 6525 defines how HTTP cookies work
-
- 14.2 Sites
-
- https://curl.haxx.se is the home of the curl project
diff --git a/docs/TheArtOfHttpScripting.md b/docs/TheArtOfHttpScripting.md
new file mode 100644
index 000000000..21a50f365
--- /dev/null
+++ b/docs/TheArtOfHttpScripting.md
@@ -0,0 +1,692 @@
+# The Art Of Scripting HTTP Requests Using Curl
+
+## Background
+
+ This document assumes that you're familiar with HTML and general networking.
+
+ The increasing amount of applications moving to the web has made "HTTP
+ Scripting" more frequently requested and wanted. To be able to automatically
+ extract information from the web, to fake users, to post or upload data to
+ web servers are all important tasks today.
+
+ Curl is a command line tool for doing all sorts of URL manipulations and
+ transfers, but this particular document will focus on how to use it when
+ doing HTTP requests for fun and profit. I will assume that you know how to
+ invoke `curl --help` or `curl --manual` to get basic information about it.
+
+ Curl is not written to do everything for you. It makes the requests, it gets
+ the data, it sends data and it retrieves the information. You probably need
+ to glue everything together using some kind of script language or repeated
+ manual invokes.
+
+## The HTTP Protocol
+
+ HTTP is the protocol used to fetch data from web servers. It is a very simple
+ protocol that is built upon TCP/IP. The protocol also allows information to
+ get sent to the server from the client using a few different methods, as will
+ be shown here.
+
+ HTTP is plain ASCII text lines being sent by the client to a server to
+ request a particular action, and then the server replies a few text lines
+ before the actual requested content is sent to the client.
+
+ The client, curl, sends a HTTP request. The request contains a method (like
+ GET, POST, HEAD etc), a number of request headers and sometimes a request
+ body. The HTTP server responds with a status line (indicating if things went
+ well), response headers and most often also a response body. The "body" part
+ is the plain data you requested, like the actual HTML or the image etc.
+
+## See the Protocol
+
+ Using curl's option [`--verbose`](https://curl.se/docs/manpage.html#-v)
+ (`-v` as a short option) will display what kind of commands curl sends to the
+ server, as well as a few other informational texts.
+
+ `--verbose` is the single most useful option when it comes to debug or even
+ understand the curl<->server interaction.
+
+ Sometimes even `--verbose` is not enough. Then
+ [`--trace`](https://curl.se/docs/manpage.html#-trace) and
+ [`--trace-ascii`]((https://curl.se/docs/manpage.html#--trace-ascii)
+ offer even more details as they show **everything** curl sends and
+ receives. Use it like this:
+
+ curl --trace-ascii debugdump.txt http://www.example.com/
+
+## See the Timing
+
+ Many times you may wonder what exactly is taking all the time, or you just
+ want to know the amount of milliseconds between two points in a transfer. For
+ those, and other similar situations, the
+ [`--trace-time`]((https://curl.se/docs/manpage.html#--trace-time) option
+ is what you need. It'll prepend the time to each trace output line:
+
+ curl --trace-ascii d.txt --trace-time http://example.com/
+
+## See the Response
+
+ By default curl sends the response to stdout. You need to redirect it
+ somewhere to avoid that, most often that is done with ` -o` or `-O`.
+
+# URL
+
+## Spec
+
+ The Uniform Resource Locator format is how you specify the address of a
+ particular resource on the Internet. You know these, you've seen URLs like
+ https://curl.se or https://yourbank.com a million times. RFC 3986 is the
+ canonical spec. And yeah, the formal name is not URL, it is URI.
+
+## Host
+
+ The host name is usually resolved using DNS or your /etc/hosts file to an IP
+ address and that's what curl will communicate with. Alternatively you specify
+ the IP address directly in the URL instead of a name.
+
+ For development and other trying out situations, you can point to a different
+ IP address for a host name than what would otherwise be used, by using curl's
+ [`--resolve`](https://curl.se/docs/manpage.html#--resolve) option:
+
+ curl --resolve www.example.org:80:127.0.0.1 http://www.example.org/
+
+## Port number
+
+ Each protocol curl supports operates on a default port number, be it over TCP
+ or in some cases UDP. Normally you don't have to take that into
+ consideration, but at times you run test servers on other ports or
+ similar. Then you can specify the port number in the URL with a colon and a
+ number immediately following the host name. Like when doing HTTP to port
+ 1234:
+
+ curl http://www.example.org:1234/
+
+ The port number you specify in the URL is the number that the server uses to
+ offer its services. Sometimes you may use a local proxy, and then you may
+ need to specify that proxy's port number separately for what curl needs to
+ connect to locally. Like when using a HTTP proxy on port 4321:
+
+ curl --proxy http://proxy.example.org:4321 http://remote.example.org/
+
+## User name and password
+
+ Some services are setup to require HTTP authentication and then you need to
+ provide name and password which is then transferred to the remote site in
+ various ways depending on the exact authentication protocol used.
+
+ You can opt to either insert the user and password in the URL or you can
+ provide them separately:
+
+ curl http://user:password@example.org/
+
+ or
+
+ curl -u user:password http://example.org/
+
+ You need to pay attention that this kind of HTTP authentication is not what
+ is usually done and requested by user-oriented websites these days. They tend
+ to use forms and cookies instead.
+
+## Path part
+
+ The path part is just sent off to the server to request that it sends back
+ the associated response. The path is what is to the right side of the slash
+ that follows the host name and possibly port number.
+
+# Fetch a page
+
+## GET
+
+ The simplest and most common request/operation made using HTTP is to GET a
+ URL. The URL could itself refer to a web page, an image or a file. The client
+ issues a GET request to the server and receives the document it asked for.
+ If you issue the command line
+
+ curl https://curl.se
+
+ you get a web page returned in your terminal window. The entire HTML document
+ that that URL holds.
+
+ All HTTP replies contain a set of response headers that are normally hidden,
+ use curl's [`--include`](https://curl.se/docs/manpage.html#-i) (`-i`)
+ option to display them as well as the rest of the document.
+
+## HEAD
+
+ You can ask the remote server for ONLY the headers by using the
+ [`--head`](https://curl.se/docs/manpage.html#-I) (`-I`) option which
+ will make curl issue a HEAD request. In some special cases servers deny the
+ HEAD method while others still work, which is a particular kind of annoyance.
+
+ The HEAD method is defined and made so that the server returns the headers
+ exactly the way it would do for a GET, but without a body. It means that you
+ may see a `Content-Length:` in the response headers, but there must not be an
+ actual body in the HEAD response.
+
+## Multiple URLs in a single command line
+
+ A single curl command line may involve one or many URLs. The most common case
+ is probably to just use one, but you can specify any amount of URLs. Yes
+ any. No limits. You'll then get requests repeated over and over for all the
+ given URLs.
+
+ Example, send two GETs:
+
+ curl http://url1.example.com http://url2.example.com
+
+ If you use [`--data`](https://curl.se/docs/manpage.html#-d) to POST to
+ the URL, using multiple URLs means that you send that same POST to all the
+ given URLs.
+
+ Example, send two POSTs:
+
+ curl --data name=curl http://url1.example.com http://url2.example.com
+
+
+## Multiple HTTP methods in a single command line
+
+ Sometimes you need to operate on several URLs in a single command line and do
+ different HTTP methods on each. For this, you'll enjoy the
+ [`--next`](https://curl.se/docs/manpage.html#-:) option. It is basically
+ a separator that separates a bunch of options from the next. All the URLs
+ before `--next` will get the same method and will get all the POST data
+ merged into one.
+
+ When curl reaches the `--next` on the command line, it'll sort of reset the
+ method and the POST data and allow a new set.
+
+ Perhaps this is best shown with a few examples. To send first a HEAD and then
+ a GET:
+
+ curl -I http://example.com --next http://example.com
+
+ To first send a POST and then a GET:
+
+ curl -d score=10 http://example.com/post.cgi --next http://example.com/results.html
+
+# HTML forms
+
+## Forms explained
+
+ Forms are the general way a website can present a HTML page with fields for
+ the user to enter data in, and then press some kind of 'OK' or 'Submit'
+ button to get that data sent to the server. The server then typically uses
+ the posted data to decide how to act. Like using the entered words to search
+ in a database, or to add the info in a bug tracking system, display the
+ entered address on a map or using the info as a login-prompt verifying that
+ the user is allowed to see what it is about to see.
+
+ Of course there has to be some kind of program on the server end to receive
+ the data you send. You cannot just invent something out of the air.
+
+## GET
+
+ A GET-form uses the method GET, as specified in HTML like:
+
+ <form method="GET" action="junk.cgi">
+ <input type=text name="birthyear">
+ <input type=submit name=press value="OK">
+ </form>
+
+ In your favorite browser, this form will appear with a text box to fill in
+ and a press-button labeled "OK". If you fill in '1905' and press the OK
+ button, your browser will then create a new URL to get for you. The URL will
+ get `junk.cgi?birthyear=1905&press=OK` appended to the path part of the
+ previous URL.
+
+ If the original form was seen on the page `www.example.com/when/birth.html`,
+ the second page you'll get will become
+ `www.example.com/when/junk.cgi?birthyear=1905&press=OK`.
+
+ Most search engines work this way.
+
+ To make curl do the GET form post for you, just enter the expected created
+ URL:
+
+ curl "http://www.example.com/when/junk.cgi?birthyear=1905&press=OK"
+
+## POST
+
+ The GET method makes all input field names get displayed in the URL field of
+ your browser. That's generally a good thing when you want to be able to
+ bookmark that page with your given data, but it is an obvious disadvantage if
+ you entered secret information in one of the fields or if there are a large
+ amount of fields creating a very long and unreadable URL.
+
+ The HTTP protocol then offers the POST method. This way the client sends the
+ data separated from the URL and thus you won't see any of it in the URL
+ address field.
+
+ The form would look very similar to the previous one:
+
+ <form method="POST" action="junk.cgi">
+ <input type=text name="birthyear">
+ <input type=submit name=press value=" OK ">
+ </form>
+
+ And to use curl to post this form with the same data filled in as before, we
+ could do it like:
+
+ curl --data "birthyear=1905&press=%20OK%20" http://www.example.com/when.cgi
+
+ This kind of POST will use the Content-Type
+ `application/x-www-form-urlencoded' and is the most widely used POST kind.
+
+ The data you send to the server MUST already be properly encoded, curl will
+ not do that for you. For example, if you want the data to contain a space,
+ you need to replace that space with %20 etc. Failing to comply with this will
+ most likely cause your data to be received wrongly and messed up.
+
+ Recent curl versions can in fact url-encode POST data for you, like this:
+
+ curl --data-urlencode "name=I am Daniel" http://www.example.com
+
+ If you repeat `--data` several times on the command line, curl will
+ concatenate all the given data pieces - and put a `&` symbol between each
+ data segment.
+
+## File Upload POST
+
+ Back in late 1995 they defined an additional way to post data over HTTP. It
+ is documented in the RFC 1867, why this method sometimes is referred to as
+ RFC1867-posting.
+
+ This method is mainly designed to better support file uploads. A form that
+ allows a user to upload a file could be written like this in HTML:
+
+ <form method="POST" enctype='multipart/form-data' action="upload.cgi">
+ <input type=file name=upload>
+ <input type=submit name=press value="OK">
+ </form>
+
+ This clearly shows that the Content-Type about to be sent is
+ `multipart/form-data`.
+
+ To post to a form like this with curl, you enter a command line like:
+
+ curl --form upload=@localfilename --form press=OK [URL]
+
+## Hidden Fields
+
+ A very common way for HTML based applications to pass state information
+ between pages is to add hidden fields to the forms. Hidden fields are already
+ filled in, they aren't displayed to the user and they get passed along just
+ as all the other fields.
+
+ A similar example form with one visible field, one hidden field and one
+ submit button could look like:
+
+ <form method="POST" action="foobar.cgi">
+ <input type=text name="birthyear">
+ <input type=hidden name="person" value="daniel">
+ <input type=submit name="press" value="OK">
+ </form>
+
+ To POST this with curl, you won't have to think about if the fields are
+ hidden or not. To curl they're all the same:
+
+ curl --data "birthyear=1905&press=OK&person=daniel" [URL]
+
+## Figure Out What A POST Looks Like
+
+ When you're about fill in a form and send to a server by using curl instead
+ of a browser, you're of course very interested in sending a POST exactly the
+ way your browser does.
+
+ An easy way to get to see this, is to save the HTML page with the form on
+ your local disk, modify the 'method' to a GET, and press the submit button
+ (you could also change the action URL if you want to).
+
+ You will then clearly see the data get appended to the URL, separated with a
+ `?`-letter as GET forms are supposed to.
+
+# HTTP upload
+
+## PUT
+
+ Perhaps the best way to upload data to a HTTP server is to use PUT. Then
+ again, this of course requires that someone put a program or script on the
+ server end that knows how to receive a HTTP PUT stream.
+
+ Put a file to a HTTP server with curl:
+
+ curl --upload-file uploadfile http://www.example.com/receive.cgi
+
+# HTTP Authentication
+
+## Basic Authentication
+
+ HTTP Authentication is the ability to tell the server your username and
+ password so that it can verify that you're allowed to do the request you're
+ doing. The Basic authentication used in HTTP (which is the type curl uses by
+ default) is **plain text** based, which means it sends username and password
+ only slightly obfuscated, but still fully readable by anyone that sniffs on
+ the network between you and the remote server.
+
+ To tell curl to use a user and password for authentication:
+
+ curl --user name:password http://www.example.com
+
+## Other Authentication
+
+ The site might require a different authentication method (check the headers
+ returned by the server), and then
+ [`--ntlm`](https://curl.se/docs/manpage.html#--ntlm),
+ [`--digest`](https://curl.se/docs/manpage.html#--digest),
+ [`--negotiate`](https://curl.se/docs/manpage.html#--negotiate) or even
+ [`--anyauth`](https://curl.se/docs/manpage.html#--anyauth) might be
+ options that suit you.
+
+## Proxy Authentication
+
+ Sometimes your HTTP access is only available through the use of a HTTP
+ proxy. This seems to be especially common at various companies. A HTTP proxy
+ may require its own user and password to allow the client to get through to
+ the Internet. To specify those with curl, run something like:
+
+ curl --proxy-user proxyuser:proxypassword curl.se
+
+ If your proxy requires the authentication to be done using the NTLM method,
+ use [`--proxy-ntlm`](https://curl.se/docs/manpage.html#--proxy-ntlm), if
+ it requires Digest use
+ [`--proxy-digest`](https://curl.se/docs/manpage.html#--proxy-digest).
+
+ If you use any one of these user+password options but leave out the password
+ part, curl will prompt for the password interactively.
+
+## Hiding credentials
+
+ Do note that when a program is run, its parameters might be possible to see
+ when listing the running processes of the system. Thus, other users may be
+ able to watch your passwords if you pass them as plain command line
+ options. There are ways to circumvent this.
+
+ It is worth noting that while this is how HTTP Authentication works, very
+ many websites will not use this concept when they provide logins etc. See the
+ Web Login chapter further below for more details on that.
+
+# More HTTP Headers
+
+## Referer
+
+ A HTTP request may include a 'referer' field (yes it is misspelled), which
+ can be used to tell from which URL the client got to this particular
+ resource. Some programs/scripts check the referer field of requests to verify
+ that this wasn't arriving from an external site or an unknown page. While
+ this is a stupid way to check something so easily forged, many scripts still
+ do it. Using curl, you can put anything you want in the referer-field and
+ thus more easily be able to fool the server into serving your request.
+
+ Use curl to set the referer field with:
+
+ curl --referer http://www.example.come http://www.example.com
+
+## User Agent
+
+ Very similar to the referer field, all HTTP requests may set the User-Agent
+ field. It names what user agent (client) that is being used. Many
+ applications use this information to decide how to display pages. Silly web
+ programmers try to make different pages for users of different browsers to
+ make them look the best possible for their particular browsers. They usually
+ also do different kinds of javascript, vbscript etc.
+
+ At times, you will see that getting a page with curl will not return the same
+ page that you see when getting the page with your browser. Then you know it
+ is time to set the User Agent field to fool the server into thinking you're
+ one of those browsers.
+
+ To make curl look like Internet Explorer 5 on a Windows 2000 box:
+
+ curl --user-agent "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)" [URL]
+
+ Or why not look like you're using Netscape 4.73 on an old Linux box:
+
+ curl --user-agent "Mozilla/4.73 [en] (X11; U; Linux 2.2.15 i686)" [URL]
+
+## Redirects
+
+## Location header
+
+ When a resource is requested from a server, the reply from the server may
+ include a hint about where the browser should go next to find this page, or a
+ new page keeping newly generated output. The header that tells the browser to
+ redirect is `Location:`.
+
+ Curl does not follow `Location:` headers by default, but will simply display
+ such pages in the same manner it displays all HTTP replies. It does however
+ feature an option that will make it attempt to follow the `Location:`
+ pointers.
+
+ To tell curl to follow a Location:
+
+ curl --location http://www.example.com
+
+ If you use curl to POST to a site that immediately redirects you to another
+ page, you can safely use
+ [`--location`](https://curl.se/docs/manpage.html#-L) (`-L`) and
+ `--data`/`--form` together. curl will only use POST in the first request, and
+ then revert to GET in the following operations.
+
+## Other redirects
+
+ Browser typically support at least two other ways of redirects that curl
+ doesn't: first the html may contain a meta refresh tag that asks the browser
+ to load a specific URL after a set number of seconds, or it may use
+ javascript to do it.
+
+# Cookies
+
+## Cookie Basics
+
+ The way the web browsers do "client side state control" is by using
+ cookies. Cookies are just names with associated contents. The cookies are
+ sent to the client by the server. The server tells the client for what path
+ and host name it wants the cookie sent back, and it also sends an expiration
+ date and a few more properties.
+
+ When a client communicates with a server with a name and path as previously
+ specified in a received cookie, the client sends back the cookies and their
+ contents to the server, unless of course they are expired.
+
+ Many applications and servers use this method to connect a series of requests
+ into a single logical session. To be able to use curl in such occasions, we
+ must be able to record and send back cookies the way the web application
+ expects them. The same way browsers deal with them.
+
+## Cookie options
+
+ The simplest way to send a few cookies to the server when getting a page with
+ curl is to add them on the command line like:
+
+ curl --cookie "name=Daniel" http://www.example.com
+
+ Cookies are sent as common HTTP headers. This is practical as it allows curl
+ to record cookies simply by recording headers. Record cookies with curl by
+ using the [`--dump-header`](https://curl.se/docs/manpage.html#-D) (`-D`)
+ option like:
+
+ curl --dump-header headers_and_cookies http://www.example.com
+
+ (Take note that the
+ [`--cookie-jar`](https://curl.se/docs/manpage.html#-c) option described
+ below is a better way to store cookies.)
+
+ Curl has a full blown cookie parsing engine built-in that comes in use if you
+ want to reconnect to a server and use cookies that were stored from a
+ previous connection (or hand-crafted manually to fool the server into
+ believing you had a previous connection). To use previously stored cookies,
+ you run curl like:
+
+ curl --cookie stored_cookies_in_file http://www.example.com
+
+ Curl's "cookie engine" gets enabled when you use the
+ [`--cookie`](https://curl.se/docs/manpage.html#-b) option. If you only
+ want curl to understand received cookies, use `--cookie` with a file that
+ doesn't exist. Example, if you want to let curl understand cookies from a
+ page and follow a location (and thus possibly send back cookies it received),
+ you can invoke it like:
+
+ curl --cookie nada --location http://www.example.com
+
+ Curl has the ability to read and write cookie files that use the same file
+ format that Netscape and Mozilla once used. It is a convenient way to share
+ cookies between scripts or invokes. The `--cookie` (`-b`) switch
+ automatically detects if a given file is such a cookie file and parses it,
+ and by using the `--cookie-jar` (`-c`) option you'll make curl write a new
+ cookie file at the end of an operation:
+
+ curl --cookie cookies.txt --cookie-jar newcookies.txt \
+ http://www.example.com
+
+# HTTPS
+
+## HTTPS is HTTP secure
+
+ There are a few ways to do secure HTTP transfers. By far the most common
+ protocol for doing this is what is generally known as HTTPS, HTTP over
+ SSL. SSL encrypts all the data that is sent and received over the network and
+ thus makes it harder for attackers to spy on sensitive information.
+
+ SSL (or TLS as the latest version of the standard is called) offers a
+ truckload of advanced features to allow all those encryptions and key
+ infrastructure mechanisms encrypted HTTP requires.
+
+ Curl supports encrypted fetches when built to use a TLS library and it can be
+ built to use one out of a fairly large set of libraries - `curl -V` will show
+ which one your curl was built to use (if any!). To get a page from a HTTPS
+ server, simply run curl like:
+
+ curl https://secure.example.com
+
+## Certificates
+
+ In the HTTPS world, you use certificates to validate that you are the one
+ you claim to be, as an addition to normal passwords. Curl supports client-
+ side certificates. All certificates are locked with a pass phrase, which you
+ need to enter before the certificate can be used by curl. The pass phrase
+ can be specified on the command line or if not, entered interactively when
+ curl queries for it. Use a certificate with curl on a HTTPS server like:
+
+ curl --cert mycert.pem https://secure.example.com
+
+ curl also tries to verify that the server is who it claims to be, by
+ verifying the server's certificate against a locally stored CA cert
+ bundle. Failing the verification will cause curl to deny the connection. You
+ must then use [`--insecure`](https://curl.se/docs/manpage.html#-k)
+ (`-k`) in case you want to tell curl to ignore that the server can't be
+ verified.
+
+ More about server certificate verification and ca cert bundles can be read in
+ the [SSLCERTS document](https://curl.se/docs/sslcerts.html).
+
+ At times you may end up with your own CA cert store and then you can tell
+ curl to use that to verify the server's certificate:
+
+ curl --cacert ca-bundle.pem https://example.com/
+
+# Custom Request Elements
+
+## Modify method and headers
+
+ Doing fancy stuff, you may need to add or change elements of a single curl
+ request.
+
+ For example, you can change the POST request to a PROPFIND and send the data
+ as `Content-Type: text/xml` (instead of the default Content-Type) like this:
+
+ curl --data "<xml>" --header "Content-Type: text/xml" \
+ --request PROPFIND example.com
+
+ You can delete a default header by providing one without content. Like you
+ can ruin the request by chopping off the Host: header:
+
+ curl --header "Host:" http://www.example.com
+
+ You can add headers the same way. Your server may want a `Destination:`
+ header, and you can add it:
+
+ curl --header "Destination: http://nowhere" http://example.com
+
+## More on changed methods
+
+ It should be noted that curl selects which methods to use on its own
+ depending on what action to ask for. `-d` will do POST, `-I` will do HEAD and
+ so on. If you use the
+ [`--request`](https://curl.se/docs/manpage.html#-X) / `-X` option you
+ can change the method keyword curl selects, but you will not modify curl's
+ behavior. This means that if you for example use -d "data" to do a POST, you
+ can modify the method to a `PROPFIND` with `-X` and curl will still think it
+ sends a POST . You can change the normal GET to a POST method by simply
+ adding `-X POST` in a command line like:
+
+ curl -X POST http://example.org/
+
+ ... but curl will still think and act as if it sent a GET so it won't send
+ any request body etc.
+
+# Web Login
+
+## Some login tricks
+
+ While not strictly just HTTP related, it still causes a lot of people
+ problems so here's the executive run-down of how the vast majority of all
+ login forms work and how to login to them using curl.
+
+ It can also be noted that to do this properly in an automated fashion, you
+ will most certainly need to script things and do multiple curl invokes etc.
+
+ First, servers mostly use cookies to track the logged-in status of the
+ client, so you will need to capture the cookies you receive in the
+ responses. Then, many sites also set a special cookie on the login page (to
+ make sure you got there through their login page) so you should make a habit
+ of first getting the login-form page to capture the cookies set there.
+
+ Some web-based login systems feature various amounts of javascript, and
+ sometimes they use such code to set or modify cookie contents. Possibly they
+ do that to prevent programmed logins, like this manual describes how to...
+ Anyway, if reading the code isn't enough to let you repeat the behavior
+ manually, capturing the HTTP requests done by your browsers and analyzing the
+ sent cookies is usually a working method to work out how to shortcut the
+ javascript need.
+
+ In the actual `<form>` tag for the login, lots of sites fill-in
+ random/session or otherwise secretly generated hidden tags and you may need
+ to first capture the HTML code for the login form and extract all the hidden
+ fields to be able to do a proper login POST. Remember that the contents need
+ to be URL encoded when sent in a normal POST.
+
+# Debug
+
+## Some debug tricks
+
+ Many times when you run curl on a site, you'll notice that the site doesn't
+ seem to respond the same way to your curl requests as it does to your
+ browser's.
+
+ Then you need to start making your curl requests more similar to your
+ browser's requests:
+
+ - Use the `--trace-ascii` option to store fully detailed logs of the requests
+ for easier analyzing and better understanding
+
+ - Make sure you check for and use cookies when needed (both reading with
+ `--cookie` and writing with `--cookie-jar`)
+
+ - Set user-agent (with [`-A`](https://curl.se/docs/manpage.html#-A)) to
+ one like a recent popular browser does
+
+ - Set referer (with [`-E`](https://curl.se/docs/manpage.html#-E)) like
+ it is set by the browser
+
+ - If you use POST, make sure you send all the fields and in the same order as
+ the browser does it.
+
+## Check what the browsers do
+
+ A very good helper to make sure you do this right, is the web browsers'
+ developers tools that let you view all headers you send and receive (even
+ when using HTTPS).
+
+ A more raw approach is to capture the HTTP traffic on the network with tools
+ such as Wireshark or tcpdump and check what headers that were sent and
+ received by the browser. (HTTPS forces you to use `SSLKEYLOGFILE` to do
+ that.)
diff --git a/docs/VERSIONS.md b/docs/VERSIONS.md
index 72a45474d..d9c1cc3de 100644
--- a/docs/VERSIONS.md
+++ b/docs/VERSIONS.md
@@ -2,7 +2,7 @@ Version Numbers and Releases
============================
Curl is not only curl. Curl is also libcurl. They're actually individually
- versioned, but they mostly follow each other rather closely.
+ versioned, but they usually follow each other closely.
The version numbering is always built up using the same system:
@@ -15,22 +15,21 @@ Version Numbers and Releases
## Bumping numbers
One of these numbers will get bumped in each new release. The numbers to the
- right of a bumped number will be reset to zero. If Z is zero, it may not be
- included in the version number.
+ right of a bumped number will be reset to zero.
The main version number will get bumped when *really* big, world colliding
changes are made. The release number is bumped when changes are performed or
things/features are added. The patch number is bumped when the changes are
mere bugfixes.
- It means that after release 1.2.3, we can release 2.0 if something really big
- has been made, 1.3 if not that big changes were made or 1.2.4 if mostly bugs
- were fixed.
+ It means that after release 1.2.3, we can release 2.0.0 if something really
+ big has been made, 1.3.0 if not that big changes were made or 1.2.4 if only
+ bugs were fixed.
Bumping, as in increasing the number with 1, is unconditionally only
affecting one of the numbers (except the ones to the right of it, that may be
set to zero). 1 becomes 2, 3 becomes 4, 9 becomes 10, 88 becomes 89 and 99
- becomes 100. So, after 1.2.9 comes 1.2.10. After 3.99.3, 3.100 might come.
+ becomes 100. So, after 1.2.9 comes 1.2.10. After 3.99.3, 3.100.0 might come.
All original curl source release archives are named according to the libcurl
version (not according to the curl client version that, as said before, might
diff --git a/docs/cmdline-opts/CMakeLists.txt b/docs/cmdline-opts/CMakeLists.txt
index a63f4eddf..ae25c5c4a 100644
--- a/docs/cmdline-opts/CMakeLists.txt
+++ b/docs/cmdline-opts/CMakeLists.txt
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/docs/cmdline-opts/Makefile.am b/docs/cmdline-opts/Makefile.am
index d778fb062..8e35db0af 100644
--- a/docs/cmdline-opts/Makefile.am
+++ b/docs/cmdline-opts/Makefile.am
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/docs/cmdline-opts/Makefile.inc b/docs/cmdline-opts/Makefile.inc
index 6a7b953bc..097be34b6 100644
--- a/docs/cmdline-opts/Makefile.inc
+++ b/docs/cmdline-opts/Makefile.inc
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -41,6 +41,7 @@ DPAGES = \
cookie.d \
create-dirs.d \
crlf.d crlfile.d \
+ curves.d \
data-ascii.d \
data-binary.d \
data-urlencode.d \
@@ -84,6 +85,7 @@ DPAGES = \
head.d header.d \
help.d \
hostpubmd5.d \
+ hsts.d \
http0.9.d \
http1.0.d \
http1.1.d http2.d \
@@ -127,6 +129,7 @@ DPAGES = \
ntlm.d ntlm-wb.d \
oauth2-bearer.d \
output.d \
+ output-dir.d \
parallel-immediate.d \
parallel-max.d \
parallel.d \
diff --git a/docs/cmdline-opts/abstract-unix-socket.d b/docs/cmdline-opts/abstract-unix-socket.d
index 1fda4e5df..8403cab9d 100644
--- a/docs/cmdline-opts/abstract-unix-socket.d
+++ b/docs/cmdline-opts/abstract-unix-socket.d
@@ -3,6 +3,7 @@ Arg: <path>
Help: Connect via abstract Unix domain socket
Added: 7.53.0
Protocols: HTTP
+Category: connection
---
Connect through an abstract Unix domain socket, instead of using the network.
Note: netstat shows the path of an abstract socket prefixed with '@', however
diff --git a/docs/cmdline-opts/alt-svc.d b/docs/cmdline-opts/alt-svc.d
index 15877a2fe..5598b59b4 100644
--- a/docs/cmdline-opts/alt-svc.d
+++ b/docs/cmdline-opts/alt-svc.d
@@ -3,6 +3,7 @@ Arg: <file name>
Protocols: HTTPS
Help: Enable alt-svc with this cache file
Added: 7.64.1
+Category: http
---
WARNING: this option is experimental. Do not use in production.
diff --git a/docs/cmdline-opts/anyauth.d b/docs/cmdline-opts/anyauth.d
index c32d1ed5e..bec0c0c86 100644
--- a/docs/cmdline-opts/anyauth.d
+++ b/docs/cmdline-opts/anyauth.d
@@ -2,6 +2,7 @@ Long: anyauth
Help: Pick any authentication method
Protocols: HTTP
See-also: proxy-anyauth basic digest
+Category: http proxy auth
---
Tells curl to figure out authentication method by itself, and use the most
secure one the remote site claims to support. This is done by first doing a
diff --git a/docs/cmdline-opts/append.d b/docs/cmdline-opts/append.d
index f001b1239..8bdb2594d 100644
--- a/docs/cmdline-opts/append.d
+++ b/docs/cmdline-opts/append.d
@@ -2,6 +2,7 @@ Short: a
Long: append
Help: Append to target file when uploading
Protocols: FTP SFTP
+Category: ftp sftp
---
When used in an upload, this makes curl append to the target file instead of
overwriting it. If the remote file doesn't exist, it will be created. Note
diff --git a/docs/cmdline-opts/basic.d b/docs/cmdline-opts/basic.d
index 09d42af9d..e222c51c1 100644
--- a/docs/cmdline-opts/basic.d
+++ b/docs/cmdline-opts/basic.d
@@ -2,6 +2,7 @@ Long: basic
Help: Use HTTP Basic Authentication
See-also: proxy-basic
Protocols: HTTP
+Category: auth
---
Tells curl to use HTTP Basic authentication with the remote host. This is the
default and this option is usually pointless, unless you use it to override a
diff --git a/docs/cmdline-opts/cacert.d b/docs/cmdline-opts/cacert.d
index 6a5678752..793d8c1ba 100644
--- a/docs/cmdline-opts/cacert.d
+++ b/docs/cmdline-opts/cacert.d
@@ -2,6 +2,7 @@ Long: cacert
Arg: <file>
Help: CA certificate to verify peer against
Protocols: TLS
+Category: tls
---
Tells curl to use the specified certificate file to verify the peer. The file
may contain multiple CA certificates. The certificate(s) must be in PEM
diff --git a/docs/cmdline-opts/capath.d b/docs/cmdline-opts/capath.d
index 0763f7a0d..4ce077a14 100644
--- a/docs/cmdline-opts/capath.d
+++ b/docs/cmdline-opts/capath.d
@@ -2,6 +2,7 @@ Long: capath
Arg: <dir>
Help: CA directory to verify peer against
Protocols: TLS
+Category: tls
---
Tells curl to use the specified certificate directory to verify the
peer. Multiple paths can be provided by separating them with ":" (e.g.
diff --git a/docs/cmdline-opts/cert-status.d b/docs/cmdline-opts/cert-status.d
index f1aaa2174..1342b092b 100644
--- a/docs/cmdline-opts/cert-status.d
+++ b/docs/cmdline-opts/cert-status.d
@@ -2,6 +2,7 @@ Long: cert-status
Protocols: TLS
Added: 7.41.0
Help: Verify the status of the server certificate
+Category: tls
---
Tells curl to verify the status of the server certificate by using the
Certificate Status Request (aka. OCSP stapling) TLS extension.
diff --git a/docs/cmdline-opts/cert-type.d b/docs/cmdline-opts/cert-type.d
index 1232ec10d..b041bcb06 100644
--- a/docs/cmdline-opts/cert-type.d
+++ b/docs/cmdline-opts/cert-type.d
@@ -3,6 +3,7 @@ Protocols: TLS
Arg: <type>
Help: Certificate type (DER/PEM/ENG)
See-also: cert key key-type
+Category: tls
---
Tells curl what type the provided client certificate is using. PEM, DER, ENG
and P12 are recognized types. If not specified, PEM is assumed.
diff --git a/docs/cmdline-opts/cert.d b/docs/cmdline-opts/cert.d
index de6b42060..2938e571f 100644
--- a/docs/cmdline-opts/cert.d
+++ b/docs/cmdline-opts/cert.d
@@ -4,6 +4,7 @@ Arg: <certificate[:password]>
Help: Client certificate file and password
Protocols: TLS
See-also: cert-type key key-type
+Category: tls
---
Tells curl to use the specified client certificate file when getting a file
with HTTPS, FTPS or another SSL-based protocol. The certificate must be in
diff --git a/docs/cmdline-opts/ciphers.d b/docs/cmdline-opts/ciphers.d
index 69e85525a..723b95923 100644
--- a/docs/cmdline-opts/ciphers.d
+++ b/docs/cmdline-opts/ciphers.d
@@ -2,10 +2,11 @@ Long: ciphers
Arg: <list of ciphers>
Help: SSL ciphers to use
Protocols: TLS
+Category: tls
---
Specifies which ciphers to use in the connection. The list of ciphers must
specify valid ciphers. Read up on SSL cipher list details on this URL:
- https://curl.haxx.se/docs/ssl-ciphers.html
+ https://curl.se/docs/ssl-ciphers.html
If this option is used several times, the last one will be used.
diff --git a/docs/cmdline-opts/compressed-ssh.d b/docs/cmdline-opts/compressed-ssh.d
index 583452ae4..849fe18b0 100644
--- a/docs/cmdline-opts/compressed-ssh.d
+++ b/docs/cmdline-opts/compressed-ssh.d
@@ -2,6 +2,7 @@ Long: compressed-ssh
Help: Enable SSH compression
Protocols: SCP SFTP
Added: 7.56.0
+Category: scp ssh
---
Enables built-in SSH compression.
This is a request, not an order; the server may or may not do it.
diff --git a/docs/cmdline-opts/compressed.d b/docs/cmdline-opts/compressed.d
index 3aca92c32..26bc1514a 100644
--- a/docs/cmdline-opts/compressed.d
+++ b/docs/cmdline-opts/compressed.d
@@ -1,6 +1,7 @@
Long: compressed
Help: Request compressed response
Protocols: HTTP
+Category: http
---
Request a compressed response using one of the algorithms curl supports, and
automatically decompress the content. Headers are not modified.
diff --git a/docs/cmdline-opts/config.d b/docs/cmdline-opts/config.d
index df3d39220..254c7044b 100644
--- a/docs/cmdline-opts/config.d
+++ b/docs/cmdline-opts/config.d
@@ -2,6 +2,7 @@ Long: config
Arg: <file>
Help: Read config from a file
Short: K
+Category: curl
---
Specify a text file to read curl arguments from. The command line arguments
@@ -28,19 +29,25 @@ Note that to be able to specify a URL in the config file, you need to specify
it using the --url option, and not by simply writing the URL on its own
line. So, it could look similar to this:
-url = "https://curl.haxx.se/docs/"
+url = "https://curl.se/docs/"
When curl is invoked, it (unless --disable is used) checks for a default
config file and uses it if found. The default config file is checked for in
the following places in this order:
-1) curl tries to find the "home dir": It first checks for the CURL_HOME and
-then the HOME environment variables. Failing that, it uses getpwuid() on
-Unix-like systems (which returns the home dir given the current user in your
-system). On Windows, it then checks for the APPDATA variable, or as a last
-resort the '%USERPROFILE%\\Application Data'.
+1) Use the CURL_HOME environment variable if set
-2) On windows, if there is no .curlrc file in the home dir, it checks for one
+2) Use the XDG_CONFIG_HOME environment variable if set (Added in 7.73.0)
+
+3) Use the HOME environment variable if set
+
+4) Non-windows: use getpwuid to find the home directory
+
+5) Windows: use APPDATA if set
+
+6) Windows: use "USERPROFILE\Application Data" if set
+
+7) On windows, if there is no .curlrc file in the home dir, it checks for one
in the same dir the curl executable is placed. On Unix-like systems, it will
simply try to load .curlrc from the determined home dir.
diff --git a/docs/cmdline-opts/connect-timeout.d b/docs/cmdline-opts/connect-timeout.d
index 3a32d8685..fa3277221 100644
--- a/docs/cmdline-opts/connect-timeout.d
+++ b/docs/cmdline-opts/connect-timeout.d
@@ -2,6 +2,7 @@ Long: connect-timeout
Arg: <seconds>
Help: Maximum time allowed for connection
See-also: max-time
+Category: connection
---
Maximum time in seconds that you allow curl's connection to take. This only
limits the connection phase, so if curl connects within the given period it
diff --git a/docs/cmdline-opts/connect-to.d b/docs/cmdline-opts/connect-to.d
index 458bfe855..2f015f8ac 100644
--- a/docs/cmdline-opts/connect-to.d
+++ b/docs/cmdline-opts/connect-to.d
@@ -3,6 +3,7 @@ Arg: <HOST1:PORT1:HOST2:PORT2>
Help: Connect to host
Added: 7.49.0
See-also: resolve header
+Category: connection
---
For a request to the given HOST1:PORT1 pair, connect to HOST2:PORT2 instead.
diff --git a/docs/cmdline-opts/continue-at.d b/docs/cmdline-opts/continue-at.d
index 733f4941e..c44d2f496 100644
--- a/docs/cmdline-opts/continue-at.d
+++ b/docs/cmdline-opts/continue-at.d
@@ -3,6 +3,7 @@ Long: continue-at
Arg: <offset>
Help: Resumed transfer offset
See-also: range
+Category: connection
---
Continue/Resume a previous file transfer at the given offset. The given offset
is the exact number of bytes that will be skipped, counting from the beginning
diff --git a/docs/cmdline-opts/cookie-jar.d b/docs/cmdline-opts/cookie-jar.d
index da79777eb..f11991f4e 100644
--- a/docs/cmdline-opts/cookie-jar.d
+++ b/docs/cmdline-opts/cookie-jar.d
@@ -3,6 +3,7 @@ Long: cookie-jar
Arg: <filename>
Protocols: HTTP
Help: Write cookies to <filename> after operation
+Category: http
---
Specify to which file you want curl to write all cookies after a completed
operation. Curl writes all cookies from its in-memory cookie storage to the
diff --git a/docs/cmdline-opts/cookie.d b/docs/cmdline-opts/cookie.d
index 467e05663..5d2c9d783 100644
--- a/docs/cmdline-opts/cookie.d
+++ b/docs/cmdline-opts/cookie.d
@@ -3,6 +3,7 @@ Long: cookie
Arg: <data|filename>
Protocols: HTTP
Help: Send cookies from string/file
+Category: http
---
Pass the data to the HTTP server in the Cookie header. It is supposedly
the data previously received from the server in a "Set-Cookie:" line. The
diff --git a/docs/cmdline-opts/create-dirs.d b/docs/cmdline-opts/create-dirs.d
index b09d96ca7..48a8fd466 100644
--- a/docs/cmdline-opts/create-dirs.d
+++ b/docs/cmdline-opts/create-dirs.d
@@ -1,5 +1,6 @@
Long: create-dirs
Help: Create necessary local directory hierarchy
+Category: curl
---
When used in conjunction with the --output option, curl will create the
necessary local directory hierarchy as needed. This option creates the dirs
diff --git a/docs/cmdline-opts/crlf.d b/docs/cmdline-opts/crlf.d
index f6694b654..50c4bef81 100644
--- a/docs/cmdline-opts/crlf.d
+++ b/docs/cmdline-opts/crlf.d
@@ -1,6 +1,7 @@
Long: crlf
Help: Convert LF to CRLF in upload
Protocols: FTP SMTP
+Category: ftp smtp
---
Convert LF to CRLF in upload. Useful for MVS (OS/390).
diff --git a/docs/cmdline-opts/crlfile.d b/docs/cmdline-opts/crlfile.d
index 0fcc63c85..360e668d1 100644
--- a/docs/cmdline-opts/crlfile.d
+++ b/docs/cmdline-opts/crlfile.d
@@ -3,6 +3,7 @@ Arg: <file>
Protocols: TLS
Help: Get a CRL list in PEM format from the given file
Added: 7.19.7
+Category: tls
---
Provide a file using PEM format with a Certificate Revocation List that may
specify peer certificates that are to be considered revoked.
diff --git a/docs/cmdline-opts/curves.d b/docs/cmdline-opts/curves.d
new file mode 100644
index 000000000..47870a278
--- /dev/null
+++ b/docs/cmdline-opts/curves.d
@@ -0,0 +1,18 @@
+Long: curves
+Arg: <algorithm list>
+Help: (EC) TLS key exchange algorithm(s) to request
+Protocols: TLS
+Added: 7.73.0
+Category: tls
+---
+Tells curl to request specific curves to use during SSL session establishment
+according to RFC 8422, 5.1. Multiple algorithms can be provided by separating
+them with ":" (e.g. "X25519:P-521"). The parameter is available identically
+in the "openssl s_client/s_server" utilities.
+
+--curves allows a OpenSSL powered curl to make SSL-connections with exactly
+the (EC) curve requested by the client, avoiding intransparent client/server
+negotiations.
+
+If this option is set, the default curves list built into openssl will be
+ignored.
diff --git a/docs/cmdline-opts/data-ascii.d b/docs/cmdline-opts/data-ascii.d
index bda4abc3d..3522f6345 100644
--- a/docs/cmdline-opts/data-ascii.d
+++ b/docs/cmdline-opts/data-ascii.d
@@ -2,5 +2,6 @@ Long: data-ascii
Arg: <data>
Help: HTTP POST ASCII data
Protocols: HTTP
+Category: http post upload
---
This is just an alias for --data.
diff --git a/docs/cmdline-opts/data-binary.d b/docs/cmdline-opts/data-binary.d
index 3f6ff2dbd..c40785ece 100644
--- a/docs/cmdline-opts/data-binary.d
+++ b/docs/cmdline-opts/data-binary.d
@@ -2,6 +2,7 @@ Long: data-binary
Arg: <data>
Help: HTTP POST binary data
Protocols: HTTP
+Category: http post upload
---
This posts data exactly as specified with no extra processing whatsoever.
diff --git a/docs/cmdline-opts/data-raw.d b/docs/cmdline-opts/data-raw.d
index 7669b4abf..4db83aefa 100644
--- a/docs/cmdline-opts/data-raw.d
+++ b/docs/cmdline-opts/data-raw.d
@@ -4,6 +4,7 @@ Protocols: HTTP
Help: HTTP POST data, '@' allowed
Added: 7.43.0
See-also: data
+Category: http post upload
---
This posts data similarly to --data but without the special
interpretation of the @ character.
diff --git a/docs/cmdline-opts/data-urlencode.d b/docs/cmdline-opts/data-urlencode.d
index 9873f3356..2f2a3645b 100644
--- a/docs/cmdline-opts/data-urlencode.d
+++ b/docs/cmdline-opts/data-urlencode.d
@@ -4,6 +4,7 @@ Help: HTTP POST data url encoded
Protocols: HTTP
See-also: data data-raw
Added: 7.18.0
+Category: http post upload
---
This posts data, similar to the other --data options with the exception
that this performs URL-encoding.
diff --git a/docs/cmdline-opts/data.d b/docs/cmdline-opts/data.d
index 280d38bc0..53ba86b36 100644
--- a/docs/cmdline-opts/data.d
+++ b/docs/cmdline-opts/data.d
@@ -5,6 +5,7 @@ Help: HTTP POST data
Protocols: HTTP MQTT
See-also: data-binary data-urlencode data-raw
Mutexed: form head upload-file
+Category: important http post upload
---
Sends the specified data in a POST request to the HTTP server, in the same way
that a browser does when a user has filled in an HTML form and presses the
diff --git a/docs/cmdline-opts/delegation.d b/docs/cmdline-opts/delegation.d
index 138d82333..fa2795f96 100644
--- a/docs/cmdline-opts/delegation.d
+++ b/docs/cmdline-opts/delegation.d
@@ -2,6 +2,7 @@ Long: delegation
Arg: <LEVEL>
Help: GSS-API delegation permission
Protocols: GSS/kerberos
+Category: auth
---
Set LEVEL to tell the server what it is allowed to delegate when it
comes to user credentials.
diff --git a/docs/cmdline-opts/digest.d b/docs/cmdline-opts/digest.d
index 5cdd9258a..da8c01e26 100644
--- a/docs/cmdline-opts/digest.d
+++ b/docs/cmdline-opts/digest.d
@@ -3,6 +3,7 @@ Help: Use HTTP Digest Authentication
Protocols: HTTP
Mutexed: basic ntlm negotiate
See-also: user proxy-digest anyauth
+Category: proxy auth http
---
Enables HTTP Digest authentication. This is an authentication scheme that
prevents the password from being sent over the wire in clear text. Use this in
diff --git a/docs/cmdline-opts/disable-eprt.d b/docs/cmdline-opts/disable-eprt.d
index a1e53c0bd..ffcf684e4 100644
--- a/docs/cmdline-opts/disable-eprt.d
+++ b/docs/cmdline-opts/disable-eprt.d
@@ -1,6 +1,7 @@
Long: disable-eprt
Help: Inhibit using EPRT or LPRT
Protocols: FTP
+Category: ftp
---
Tell curl to disable the use of the EPRT and LPRT commands when doing active
FTP transfers. Curl will normally always first attempt to use EPRT, then LPRT
diff --git a/docs/cmdline-opts/disable-epsv.d b/docs/cmdline-opts/disable-epsv.d
index 6d2cb7089..df1de8304 100644
--- a/docs/cmdline-opts/disable-epsv.d
+++ b/docs/cmdline-opts/disable-epsv.d
@@ -1,6 +1,7 @@
Long: disable-epsv
Help: Inhibit using EPSV
Protocols: FTP
+Category: ftp
---
(FTP) Tell curl to disable the use of the EPSV command when doing passive FTP
transfers. Curl will normally always first attempt to use EPSV before PASV,
diff --git a/docs/cmdline-opts/disable.d b/docs/cmdline-opts/disable.d
index 20b27b4c5..688fc0c54 100644
--- a/docs/cmdline-opts/disable.d
+++ b/docs/cmdline-opts/disable.d
@@ -1,6 +1,7 @@
Long: disable
Short: q
Help: Disable .curlrc
+Category: curl
---
If used as the first parameter on the command line, the \fIcurlrc\fP config
file will not be read and used. See the --config for details on the default
diff --git a/docs/cmdline-opts/disallow-username-in-url.d b/docs/cmdline-opts/disallow-username-in-url.d
index a7f46ea15..e124f675a 100644
--- a/docs/cmdline-opts/disallow-username-in-url.d
+++ b/docs/cmdline-opts/disallow-username-in-url.d
@@ -3,5 +3,6 @@ Help: Disallow username in url
Protocols: HTTP
Added: 7.61.0
See-also: proto
+Category: curl http
---
This tells curl to exit if passed a url containing a username.
diff --git a/docs/cmdline-opts/dns-interface.d b/docs/cmdline-opts/dns-interface.d
index 45e5af263..3cb818ae3 100644
--- a/docs/cmdline-opts/dns-interface.d
+++ b/docs/cmdline-opts/dns-interface.d
@@ -5,6 +5,7 @@ Protocols: DNS
See-also: dns-ipv4-addr dns-ipv6-addr
Added: 7.33.0
Requires: c-ares
+Category: dns
---
Tell curl to send outgoing DNS requests through <interface>. This option is a
counterpart to --interface (which does not affect DNS). The supplied string
diff --git a/docs/cmdline-opts/dns-ipv4-addr.d b/docs/cmdline-opts/dns-ipv4-addr.d
index 597b85884..5ebdda5ca 100644
--- a/docs/cmdline-opts/dns-ipv4-addr.d
+++ b/docs/cmdline-opts/dns-ipv4-addr.d
@@ -5,6 +5,7 @@ Protocols: DNS
See-also: dns-interface dns-ipv6-addr
Added: 7.33.0
Requires: c-ares
+Category: dns
---
Tell curl to bind to <ip-address> when making IPv4 DNS requests, so that
the DNS requests originate from this address. The argument should be a
diff --git a/docs/cmdline-opts/dns-ipv6-addr.d b/docs/cmdline-opts/dns-ipv6-addr.d
index 581f01953..10e807646 100644
--- a/docs/cmdline-opts/dns-ipv6-addr.d
+++ b/docs/cmdline-opts/dns-ipv6-addr.d
@@ -5,6 +5,7 @@ Protocols: DNS
See-also: dns-interface dns-ipv4-addr
Added: 7.33.0
Requires: c-ares
+Category: dns
---
Tell curl to bind to <ip-address> when making IPv6 DNS requests, so that
the DNS requests originate from this address. The argument should be a
diff --git a/docs/cmdline-opts/dns-servers.d b/docs/cmdline-opts/dns-servers.d
index a98fd07d8..8665426a8 100644
--- a/docs/cmdline-opts/dns-servers.d
+++ b/docs/cmdline-opts/dns-servers.d
@@ -3,6 +3,7 @@ Arg: <addresses>
Help: DNS server addrs to use
Requires: c-ares
Added: 7.33.0
+Category: dns
---
Set the list of DNS servers to be used instead of the system default.
The list of IP addresses should be separated with commas. Port numbers
diff --git a/docs/cmdline-opts/doh-url.d b/docs/cmdline-opts/doh-url.d
index c871c4d22..7fce4460d 100644
--- a/docs/cmdline-opts/doh-url.d
+++ b/docs/cmdline-opts/doh-url.d
@@ -3,6 +3,7 @@ Arg: <URL>
Help: Resolve host names over DOH
Protocols: all
Added: 7.62.0
+Category: dns
---
Specifies which DNS-over-HTTPS (DOH) server to use to resolve hostnames,
instead of using the default name resolver mechanism. The URL must be HTTPS.
diff --git a/docs/cmdline-opts/dump-header.d b/docs/cmdline-opts/dump-header.d
index 33c6674e8..8449dfe85 100644
--- a/docs/cmdline-opts/dump-header.d
+++ b/docs/cmdline-opts/dump-header.d
@@ -4,6 +4,7 @@ Arg: <filename>
Help: Write the received headers to <filename>
Protocols: HTTP FTP
See-also: output
+Category: http ftp
---
Write the received protocol headers to the specified file.
diff --git a/docs/cmdline-opts/egd-file.d b/docs/cmdline-opts/egd-file.d
index c22790f6a..05ede9ad1 100644
--- a/docs/cmdline-opts/egd-file.d
+++ b/docs/cmdline-opts/egd-file.d
@@ -3,6 +3,7 @@ Arg: <file>
Help: EGD socket path for random data
Protocols: TLS
See-also: random-file
+Category: tls
---
Specify the path name to the Entropy Gathering Daemon socket. The socket is
used to seed the random engine for SSL connections.
diff --git a/docs/cmdline-opts/engine.d b/docs/cmdline-opts/engine.d
index cde1a4773..9ed0cf1b0 100644
--- a/docs/cmdline-opts/engine.d
+++ b/docs/cmdline-opts/engine.d
@@ -2,6 +2,7 @@ Long: engine
Arg: <name>
Help: Crypto engine to use
Protocols: TLS
+Category: tls
---
Select the OpenSSL crypto engine to use for cipher operations. Use --engine
list to print a list of build-time supported engines. Note that not all (or
diff --git a/docs/cmdline-opts/etag-compare.d b/docs/cmdline-opts/etag-compare.d
index 1a698a8ff..cd8fe4a33 100644
--- a/docs/cmdline-opts/etag-compare.d
+++ b/docs/cmdline-opts/etag-compare.d
@@ -3,6 +3,7 @@ Arg: <file>
Help: Pass an ETag from a file as a custom header
Protocols: HTTP
Added: 7.68.0
+Category: http
---
This option makes a conditional HTTP request for the specific
ETag read from the given file by sending a custom If-None-Match
@@ -14,5 +15,5 @@ line with a desired ETag. An empty file is parsed as an empty ETag.
Use the option --etag-save to first save the ETag from a response, and
then use this option to compare using the saved ETag in a subsequent request.
-\fCOMPARISON\fP: There are 2 types of comparison or ETags, Weak and Strong.
+\fBCOMPARISON\fP: There are 2 types of comparison or ETags: Weak and Strong.
This option expects, and uses a strong comparison.
diff --git a/docs/cmdline-opts/etag-save.d b/docs/cmdline-opts/etag-save.d
index 214723ff5..95d1615ae 100644
--- a/docs/cmdline-opts/etag-save.d
+++ b/docs/cmdline-opts/etag-save.d
@@ -3,14 +3,15 @@ Arg: <file>
Help: Parse ETag from a request and save it to a file
Protocols: HTTP
Added: 7.68.0
+Category: http
---
This option saves an HTTP ETag to the specified file. Etag is
usually part of headers returned by a request. When server sends an
ETag, it must be enveloped by a double quote. This option extracts the
ETag without the double quotes and saves it into the <file>.
-A server can send a week ETag which is prefixed by "W/". This identifier
+A server can send a weak ETag which is prefixed by "W/". This identifier
is not considered, and only relevant ETag between quotation marks is parsed.
-It an ETag wasn't send by the server or it cannot be parsed, and empty
+It an ETag wasn't sent by the server or it cannot be parsed, an empty
file is created.
diff --git a/docs/cmdline-opts/expect100-timeout.d b/docs/cmdline-opts/expect100-timeout.d
index c88f0b84f..431a529c2 100644
--- a/docs/cmdline-opts/expect100-timeout.d
+++ b/docs/cmdline-opts/expect100-timeout.d
@@ -4,6 +4,7 @@ Help: How long to wait for 100-continue
Protocols: HTTP
Added: 7.47.0
See-also: connect-timeout
+Category: http
---
Maximum time in seconds that you allow curl to wait for a 100-continue
response when curl emits an Expects: 100-continue header in its request. By
diff --git a/docs/cmdline-opts/fail-early.d b/docs/cmdline-opts/fail-early.d
index 375d4c919..3fbe238af 100644
--- a/docs/cmdline-opts/fail-early.d
+++ b/docs/cmdline-opts/fail-early.d
@@ -1,6 +1,7 @@
Long: fail-early
Help: Fail on first transfer error, do not continue
Added: 7.52.0
+Category: curl
---
Fail and exit on the first detected transfer error.
diff --git a/docs/cmdline-opts/fail.d b/docs/cmdline-opts/fail.d
index c46c571bf..7fc76fb6a 100644
--- a/docs/cmdline-opts/fail.d
+++ b/docs/cmdline-opts/fail.d
@@ -2,6 +2,7 @@ Long: fail
Short: f
Protocols: HTTP
Help: Fail silently (no output at all) on HTTP errors
+Category: important http
---
Fail silently (no output at all) on server errors. This is mostly done to
better enable scripts etc to better deal with failed attempts. In normal cases
diff --git a/docs/cmdline-opts/false-start.d b/docs/cmdline-opts/false-start.d
index 65a8afb8f..abeff0eb5 100644
--- a/docs/cmdline-opts/false-start.d
+++ b/docs/cmdline-opts/false-start.d
@@ -2,6 +2,7 @@ Long: false-start
Help: Enable TLS False Start
Protocols: TLS
Added: 7.42.0
+Category: tls
---
Tells curl to use false start during the TLS handshake. False start is a mode
where a TLS client will start sending application data before verifying the
diff --git a/docs/cmdline-opts/form-string.d b/docs/cmdline-opts/form-string.d
index 49d0d44ef..04d2578c5 100644
--- a/docs/cmdline-opts/form-string.d
+++ b/docs/cmdline-opts/form-string.d
@@ -3,6 +3,7 @@ Help: Specify multipart MIME data
Protocols: HTTP SMTP IMAP
Arg: <name=string>
See-also: form
+Category: http upload
---
Similar to --form except that the value string for the named parameter is used
literally. Leading \&'@' and \&'<' characters, and the \&';type=' string in
diff --git a/docs/cmdline-opts/form.d b/docs/cmdline-opts/form.d
index 7f1aa31c3..3cd8dce75 100644
--- a/docs/cmdline-opts/form.d
+++ b/docs/cmdline-opts/form.d
@@ -4,6 +4,7 @@ Arg: <name=content>
Help: Specify multipart MIME data
Protocols: HTTP SMTP IMAP
Mutexed: data head upload-file
+Category: http upload
---
For HTTP protocol family, this lets curl emulate a filled-in form in which a
user has pressed the submit button. This causes curl to POST data using the
diff --git a/docs/cmdline-opts/ftp-account.d b/docs/cmdline-opts/ftp-account.d
index 013c4f37b..bc04ba047 100644
--- a/docs/cmdline-opts/ftp-account.d
+++ b/docs/cmdline-opts/ftp-account.d
@@ -3,6 +3,7 @@ Arg: <data>
Help: Account data string
Protocols: FTP
Added: 7.13.0
+Category: ftp auth
---
When an FTP server asks for "account data" after user name and password has
been provided, this data is sent off using the ACCT command.
diff --git a/docs/cmdline-opts/ftp-alternative-to-user.d b/docs/cmdline-opts/ftp-alternative-to-user.d
index 8982ba8b8..171484906 100644
--- a/docs/cmdline-opts/ftp-alternative-to-user.d
+++ b/docs/cmdline-opts/ftp-alternative-to-user.d
@@ -3,6 +3,7 @@ Arg: <command>
Help: String to replace USER [name]
Protocols: FTP
Added: 7.15.5
+Category: ftp
---
If authenticating with the USER and PASS commands fails, send this command.
When connecting to Tumbleweed's Secure Transport server over FTPS using a
diff --git a/docs/cmdline-opts/ftp-create-dirs.d b/docs/cmdline-opts/ftp-create-dirs.d
index ede57100d..5d9dfda46 100644
--- a/docs/cmdline-opts/ftp-create-dirs.d
+++ b/docs/cmdline-opts/ftp-create-dirs.d
@@ -2,6 +2,7 @@ Long: ftp-create-dirs
Protocols: FTP SFTP
Help: Create the remote dirs if not present
See-also: create-dirs
+Category: ftp sftp curl
---
When an FTP or SFTP URL/operation uses a path that doesn't currently exist on
the server, the standard behavior of curl is to fail. Using this option, curl
diff --git a/docs/cmdline-opts/ftp-method.d b/docs/cmdline-opts/ftp-method.d
index 95aa522e8..149340b82 100644
--- a/docs/cmdline-opts/ftp-method.d
+++ b/docs/cmdline-opts/ftp-method.d
@@ -3,6 +3,7 @@ Arg: <method>
Help: Control CWD usage
Protocols: FTP
Added: 7.15.1
+Category: ftp
---
Control what method curl should use to reach a file on an FTP(S)
server. The method argument should be one of the following alternatives:
diff --git a/docs/cmdline-opts/ftp-pasv.d b/docs/cmdline-opts/ftp-pasv.d
index 44103e21a..cbd548de3 100644
--- a/docs/cmdline-opts/ftp-pasv.d
+++ b/docs/cmdline-opts/ftp-pasv.d
@@ -3,6 +3,7 @@ Help: Use PASV/EPSV instead of PORT
Protocols: FTP
Added: 7.11.0
See-also: disable-epsv
+Category: ftp
---
Use passive mode for the data connection. Passive is the internal default
behavior, but using this option can be used to override a previous --ftp-port
diff --git a/docs/cmdline-opts/ftp-port.d b/docs/cmdline-opts/ftp-port.d
index e4b145608..9bb1d43f0 100644
--- a/docs/cmdline-opts/ftp-port.d
+++ b/docs/cmdline-opts/ftp-port.d
@@ -4,6 +4,7 @@ Help: Use PORT instead of PASV
Short: P
Protocols: FTP
See-also: ftp-pasv disable-eprt
+Category: ftp
---
Reverses the default initiator/listener roles when connecting with FTP. This
option makes curl use active mode. curl then tells the server to connect back
diff --git a/docs/cmdline-opts/ftp-pret.d b/docs/cmdline-opts/ftp-pret.d
index dac4c3531..e9c7d251a 100644
--- a/docs/cmdline-opts/ftp-pret.d
+++ b/docs/cmdline-opts/ftp-pret.d
@@ -2,6 +2,7 @@ Long: ftp-pret
Help: Send PRET before PASV
Protocols: FTP
Added: 7.20.0
+Category: ftp
---
Tell curl to send a PRET command before PASV (and EPSV). Certain FTP servers,
mainly drftpd, require this non-standard command for directory listings as
diff --git a/docs/cmdline-opts/ftp-skip-pasv-ip.d b/docs/cmdline-opts/ftp-skip-pasv-ip.d
index da6ab11fc..bcf4e7e62 100644
--- a/docs/cmdline-opts/ftp-skip-pasv-ip.d
+++ b/docs/cmdline-opts/ftp-skip-pasv-ip.d
@@ -3,10 +3,13 @@ Help: Skip the IP address for PASV
Protocols: FTP
Added: 7.14.2
See-also: ftp-pasv
+Category: ftp
---
Tell curl to not use the IP address the server suggests in its response
to curl's PASV command when curl connects the data connection. Instead curl
will re-use the same IP address it already uses for the control
connection.
+Since curl 7.74.0 this option is enabled by default.
+
This option has no effect if PORT, EPRT or EPSV is used instead of PASV.
diff --git a/docs/cmdline-opts/ftp-ssl-ccc-mode.d b/docs/cmdline-opts/ftp-ssl-ccc-mode.d
index be1029498..6289e544a 100644
--- a/docs/cmdline-opts/ftp-ssl-ccc-mode.d
+++ b/docs/cmdline-opts/ftp-ssl-ccc-mode.d
@@ -4,6 +4,7 @@ Help: Set CCC mode
Protocols: FTP
Added: 7.16.2
See-also: ftp-ssl-ccc
+Category: ftp tls
---
Sets the CCC mode. The passive mode will not initiate the shutdown, but
instead wait for the server to do it, and will not reply to the shutdown from
diff --git a/docs/cmdline-opts/ftp-ssl-ccc.d b/docs/cmdline-opts/ftp-ssl-ccc.d
index c6edc5b39..33cab4302 100644
--- a/docs/cmdline-opts/ftp-ssl-ccc.d
+++ b/docs/cmdline-opts/ftp-ssl-ccc.d
@@ -3,6 +3,7 @@ Help: Send CCC after authenticating
Protocols: FTP
See-also: ssl ftp-ssl-ccc-mode
Added: 7.16.1
+Category: ftp tls
---
Use CCC (Clear Command Channel) Shuts down the SSL/TLS layer after
authenticating. The rest of the control channel communication will be
diff --git a/docs/cmdline-opts/ftp-ssl-control.d b/docs/cmdline-opts/ftp-ssl-control.d
index 87a822531..5191353dd 100644
--- a/docs/cmdline-opts/ftp-ssl-control.d
+++ b/docs/cmdline-opts/ftp-ssl-control.d
@@ -2,6 +2,7 @@ Long: ftp-ssl-control
Help: Require SSL/TLS for FTP login, clear for transfer
Protocols: FTP
Added: 7.16.0
+Category: ftp tls
---
Require SSL/TLS for the FTP login, clear for transfer. Allows secure
authentication, but non-encrypted data transfers for efficiency. Fails the
diff --git a/docs/cmdline-opts/gen.pl b/docs/cmdline-opts/gen.pl
index ef19e2448..2e5059ab4 100755
--- a/docs/cmdline-opts/gen.pl
+++ b/docs/cmdline-opts/gen.pl
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -43,6 +43,7 @@ my %helplong;
my %arglong;
my %redirlong;
my %protolong;
+my %catlong;
# get the long name version, return the man page string
sub manpageify {
@@ -126,6 +127,7 @@ sub single {
my $arg;
my $mutexed;
my $requires;
+ my $category;
my $seealso;
my $magic; # cmdline special option
while(<F>) {
@@ -159,6 +161,9 @@ sub single {
elsif(/^Requires: *(.*)/i) {
$requires=$1;
}
+ elsif(/^Category: *(.*)/i) {
+ $category=$1;
+ }
elsif(/^Help: *(.*)/i) {
;
}
@@ -166,6 +171,9 @@ sub single {
if(!$long) {
print STDERR "WARN: no 'Long:' in $f\n";
}
+ if(!$category) {
+ print STDERR "WARN: no 'Category:' in $f\n";
+ }
last;
}
else {
@@ -218,12 +226,24 @@ sub single {
if($seealso) {
my @m=split(/ /, $seealso);
my $mstr;
+ my $and = 0;
+ my $num = scalar(@m);
+ if($num > 2) {
+ # use commas up to this point
+ $and = $num - 1;
+ }
+ my $i = 0;
for my $k (@m) {
if(!$helplong{$k}) {
print STDERR "WARN: $f see-alsos a non-existing option: $k\n";
}
my $l = manpageify($k);
- $mstr .= sprintf "%s$l", $mstr?" and ":"";
+ my $sep = " and";
+ if($and && ($i < $and)) {
+ $sep = ",";
+ }
+ $mstr .= sprintf "%s$l", $mstr?"$sep ":"";
+ $i++;
}
push @foot, seealso($standalone, $mstr);
}
@@ -264,6 +284,7 @@ sub getshortlong {
my $help;
my $arg;
my $protocols;
+ my $category;
while(<F>) {
if(/^Short: (.)/i) {
$short=$1;
@@ -280,6 +301,9 @@ sub getshortlong {
elsif(/^Protocols: (.*)/i) {
$protocols=$1;
}
+ elsif(/^Category: (.*)/i) {
+ $category=$1;
+ }
elsif(/^---/) {
last;
}
@@ -293,6 +317,7 @@ sub getshortlong {
$helplong{$long}=$help;
$arglong{$long}=$arg;
$protolong{$long}=$protocols;
+ $catlong{$long}=$category;
}
}
@@ -318,6 +343,8 @@ sub listhelp {
foreach my $f (sort keys %helplong) {
my $long = $f;
my $short = $optlong{$long};
+ my @categories = split ' ', $catlong{$long};
+ my $bitmask;
my $opt;
if(defined($short) && $long) {
@@ -326,7 +353,13 @@ sub listhelp {
elsif($long && !$short) {
$opt = " --$long";
}
-
+ for my $i (0 .. $#categories) {
+ $bitmask .= 'CURLHELP_' . uc $categories[$i];
+ # If not last element, append |
+ if($i < $#categories) {
+ $bitmask .= ' | ';
+ }
+ }
my $arg = $arglong{$long};
if($arg) {
$opt .= " $arg";
@@ -334,7 +367,7 @@ sub listhelp {
my $desc = $helplong{$f};
$desc =~ s/\"/\\\"/g; # escape double quotes
- my $line = sprintf " {\"%s\",\n \"%s\"},\n", $opt, $desc;
+ my $line = sprintf " {\"%s\",\n \"%s\",\n %s},\n", $opt, $desc, $bitmask;
if(length($opt) + length($desc) > 78) {
print STDERR "WARN: the --$long line is too long\n";
@@ -343,6 +376,25 @@ sub listhelp {
}
}
+sub listcats {
+ my %allcats;
+ foreach my $f (sort keys %helplong) {
+ my @categories = split ' ', $catlong{$f};
+ foreach (@categories) {
+ $allcats{$_} = undef;
+ }
+ }
+ my @categories;
+ foreach my $key (keys %allcats) {
+ push @categories, $key;
+ }
+ @categories = sort @categories;
+ unshift @categories, 'hidden';
+ for my $i (0..$#categories) {
+ print '#define ' . 'CURLHELP_' . uc($categories[$i]) . ' ' . "1u << " . $i . "u\n";
+ }
+}
+
sub mainpage {
my (@files) = @_;
# show the page header
@@ -396,8 +448,12 @@ sub getargs {
showprotocols();
return;
}
+ elsif($f eq "listcats") {
+ listcats();
+ return;
+ }
- print "Usage: gen.pl <mainpage/listhelp/single FILE/protos> [files]\n";
+ print "Usage: gen.pl <mainpage/listhelp/single FILE/protos/listcats> [files]\n";
}
#------------------------------------------------------------------------
diff --git a/docs/cmdline-opts/get.d b/docs/cmdline-opts/get.d
index be7cb25f0..d529bb4e0 100644
--- a/docs/cmdline-opts/get.d
+++ b/docs/cmdline-opts/get.d
@@ -1,6 +1,7 @@
Long: get
Short: G
Help: Put the post data in the URL and use GET
+Category: http upload
---
When used, this option will make all data specified with --data, --data-binary
or --data-urlencode to be used in an HTTP GET request instead of the POST
diff --git a/docs/cmdline-opts/globoff.d b/docs/cmdline-opts/globoff.d
index fff6516b6..4b5f30de9 100644
--- a/docs/cmdline-opts/globoff.d
+++ b/docs/cmdline-opts/globoff.d
@@ -1,6 +1,7 @@
Long: globoff
Short: g
Help: Disable URL sequences and ranges using {} and []
+Category: curl
---
This option switches off the "URL globbing parser". When you set this option,
you can specify URLs that contain the letters {}[] without having them being
diff --git a/docs/cmdline-opts/happy-eyeballs-timeout-ms.d b/docs/cmdline-opts/happy-eyeballs-timeout-ms.d
index 611a8f1d8..ceff2a7df 100644
--- a/docs/cmdline-opts/happy-eyeballs-timeout-ms.d
+++ b/docs/cmdline-opts/happy-eyeballs-timeout-ms.d
@@ -2,6 +2,7 @@ Long: happy-eyeballs-timeout-ms
Arg: <milliseconds>
Help: Time for IPv6 before trying IPv4
Added: 7.59.0
+Category: connection
---
Happy eyeballs is an algorithm that attempts to connect to both IPv4 and IPv6
addresses for dual-stack hosts, preferring IPv6 first for the number of
diff --git a/docs/cmdline-opts/haproxy-protocol.d b/docs/cmdline-opts/haproxy-protocol.d
index cc41c9c44..835820465 100644
--- a/docs/cmdline-opts/haproxy-protocol.d
+++ b/docs/cmdline-opts/haproxy-protocol.d
@@ -2,6 +2,7 @@ Long: haproxy-protocol
Help: Send HAProxy PROXY protocol v1 header
Protocols: HTTP
Added: 7.60.0
+Category: http proxy
---
Send a HAProxy PROXY protocol v1 header at the beginning of the connection. This
is used by some load balancers and reverse proxies to indicate the client's
diff --git a/docs/cmdline-opts/head.d b/docs/cmdline-opts/head.d
index 350a100f6..6fe468511 100644
--- a/docs/cmdline-opts/head.d
+++ b/docs/cmdline-opts/head.d
@@ -2,6 +2,7 @@ Long: head
Short: I
Help: Show document info only
Protocols: HTTP FTP FILE
+Category: http ftp file
---
Fetch the headers only! HTTP-servers feature the command HEAD which this uses
to get nothing but the header of a document. When used on an FTP or FILE file,
diff --git a/docs/cmdline-opts/header.d b/docs/cmdline-opts/header.d
index d8292ed77..980467d5b 100644
--- a/docs/cmdline-opts/header.d
+++ b/docs/cmdline-opts/header.d
@@ -3,6 +3,8 @@ Short: H
Arg: <header/@file>
Help: Pass custom header(s) to server
Protocols: HTTP
+Category: http
+See-also: user-agent referer
---
Extra header to include in the request when sending HTTP to a server. You may
specify any number of extra headers. Note that if you should add a custom
@@ -17,17 +19,18 @@ as \-H \&"X-Custom-Header;" to send "X-Custom-Header:".
curl will make sure that each header you add/replace is sent with the proper
end-of-line marker, you should thus \fBnot\fP add that as a part of the header
-content: do not add newlines or carriage returns, they will only mess things up
-for you.
+content: do not add newlines or carriage returns, they will only mess things
+up for you.
-Starting in 7.55.0, this option can take an argument in @filename style, which
-then adds a header for each line in the input file. Using @- will make curl
-read the header file from stdin.
+This option can take an argument in @filename style, which then adds a header
+for each line in the input file. Using @- will make curl read the header file
+from stdin. Added in 7.55.0.
-See also the --user-agent and --referer options.
+You need --proxy-header to send custom headers intended for a HTTP
+proxy. Added in 7.37.0.
-Starting in 7.37.0, you need --proxy-header to send custom headers intended
-for a proxy.
+Passing on a "Transfer-Encoding: chunked" header when doing a HTTP request
+with a request body, will make curl send the data using chunked encoding.
Example:
diff --git a/docs/cmdline-opts/help.d b/docs/cmdline-opts/help.d
index 64aa696d4..bf80b7818 100644
--- a/docs/cmdline-opts/help.d
+++ b/docs/cmdline-opts/help.d
@@ -1,6 +1,12 @@
Long: help
+Arg: <category>
Short: h
-Help: This help text
+Help: Get help for commands
+Category: important curl
---
-Usage help. This lists all current command line options with a short
-description.
+Usage help. This lists all commands of the <category>.
+If no arg was provided, curl will display the most important
+command line arguments and the list of categories.
+If the argument "all" was provided, curl will display all options available.
+If the argument "category" was provided, curl will display all categories and
+their meanings.
diff --git a/docs/cmdline-opts/hostpubmd5.d b/docs/cmdline-opts/hostpubmd5.d
index a85115803..c926ed8b5 100644
--- a/docs/cmdline-opts/hostpubmd5.d
+++ b/docs/cmdline-opts/hostpubmd5.d
@@ -3,6 +3,7 @@ Arg: <md5>
Help: Acceptable MD5 hash of the host public key
Protocols: SFTP SCP
Added: 7.17.1
+Category: sftp scp
---
Pass a string containing 32 hexadecimal digits. The string should
be the 128 bit MD5 checksum of the remote host's public key, curl will refuse
diff --git a/docs/cmdline-opts/hsts.d b/docs/cmdline-opts/hsts.d
new file mode 100644
index 000000000..2399084bf
--- /dev/null
+++ b/docs/cmdline-opts/hsts.d
@@ -0,0 +1,18 @@
+Long: hsts
+Arg: <file name>
+Protocols: HTTPS
+Help: Enable HSTS with this cache file
+Added: 7.74.0
+Category: http
+---
+WARNING: this option is experimental. Do not use in production.
+
+This option enables HSTS for the transfer. If the file name points to an
+existing HSTS cache file, that will be used. After a completed transfer, the
+cache will be saved to the file name again if it has been modified.
+
+Specify a "" file name (zero length) to avoid loading/saving and make curl
+just handle HSTS in memory.
+
+If this option is used several times, curl will load contents from all the
+files but the last one will be used for saving.
diff --git a/docs/cmdline-opts/http0.9.d b/docs/cmdline-opts/http0.9.d
index 7e783f696..954c22a17 100644
--- a/docs/cmdline-opts/http0.9.d
+++ b/docs/cmdline-opts/http0.9.d
@@ -3,6 +3,7 @@ Tags: Versions
Protocols: HTTP
Added:
Help: Allow HTTP 0.9 responses
+Category: http
---
Tells curl to be fine with HTTP version 0.9 response.
diff --git a/docs/cmdline-opts/http1.0.d b/docs/cmdline-opts/http1.0.d
index d9bbd76f0..a4059dbf0 100644
--- a/docs/cmdline-opts/http1.0.d
+++ b/docs/cmdline-opts/http1.0.d
@@ -5,6 +5,7 @@ Protocols: HTTP
Added:
Mutexed: http1.1 http2
Help: Use HTTP 1.0
+Category: http
---
Tells curl to use HTTP version 1.0 instead of using its internally preferred
HTTP version.
diff --git a/docs/cmdline-opts/http1.1.d b/docs/cmdline-opts/http1.1.d
index f1e6b5c3b..a71a40bab 100644
--- a/docs/cmdline-opts/http1.1.d
+++ b/docs/cmdline-opts/http1.1.d
@@ -4,5 +4,6 @@ Protocols: HTTP
Added: 7.33.0
Mutexed: http1.0 http2
Help: Use HTTP 1.1
+Category: http
---
Tells curl to use HTTP version 1.1.
diff --git a/docs/cmdline-opts/http2-prior-knowledge.d b/docs/cmdline-opts/http2-prior-knowledge.d
index f793f775d..ea2906edb 100644
--- a/docs/cmdline-opts/http2-prior-knowledge.d
+++ b/docs/cmdline-opts/http2-prior-knowledge.d
@@ -5,6 +5,7 @@ Added: 7.49.0
Mutexed: http1.1 http1.0 http2
Requires: HTTP/2
Help: Use HTTP 2 without HTTP/1.1 Upgrade
+Category: http
---
Tells curl to issue its non-TLS HTTP requests using HTTP/2 without HTTP/1.1
Upgrade. It requires prior knowledge that the server supports HTTP/2 straight
diff --git a/docs/cmdline-opts/http2.d b/docs/cmdline-opts/http2.d
index cf8f2988e..197515ee8 100644
--- a/docs/cmdline-opts/http2.d
+++ b/docs/cmdline-opts/http2.d
@@ -7,5 +7,6 @@ Requires: HTTP/2
See-also: no-alpn
Help: Use HTTP 2
See-also: http1.1 http3
+Category: http
---
Tells curl to use HTTP version 2.
diff --git a/docs/cmdline-opts/http3.d b/docs/cmdline-opts/http3.d
index 8265937a3..478b662aa 100644
--- a/docs/cmdline-opts/http3.d
+++ b/docs/cmdline-opts/http3.d
@@ -6,6 +6,7 @@ Mutexed: http1.1 http1.0 http2 http2-prior-knowledge
Requires: HTTP/3
Help: Use HTTP v3
See-also: http1.1 http2
+Category: http
---
WARNING: this option is experimental. Do not use in production.
diff --git a/docs/cmdline-opts/ignore-content-length.d b/docs/cmdline-opts/ignore-content-length.d
index 53524f518..82ac5da09 100644
--- a/docs/cmdline-opts/ignore-content-length.d
+++ b/docs/cmdline-opts/ignore-content-length.d
@@ -1,6 +1,7 @@
Long: ignore-content-length
Help: Ignore the size of the remote resource
Protocols: FTP HTTP
+Category: http ftp
---
For HTTP, Ignore the Content-Length header. This is particularly useful for
servers running Apache 1.x, which will report incorrect Content-Length for
diff --git a/docs/cmdline-opts/include.d b/docs/cmdline-opts/include.d
index 9d282dd16..250d4accf 100644
--- a/docs/cmdline-opts/include.d
+++ b/docs/cmdline-opts/include.d
@@ -2,6 +2,7 @@ Long: include
Short: i
Help: Include protocol response headers in the output
See-also: verbose
+Category: important verbose
---
Include the HTTP response headers in the output. The HTTP response headers can
include things like server name, cookies, date of the document, HTTP version
diff --git a/docs/cmdline-opts/insecure.d b/docs/cmdline-opts/insecure.d
index 49b0a4322..636f121e2 100644
--- a/docs/cmdline-opts/insecure.d
+++ b/docs/cmdline-opts/insecure.d
@@ -3,6 +3,7 @@ Short: k
Help: Allow insecure server connections when using SSL
Protocols: TLS
See-also: proxy-insecure cacert
+Category: tls
---
By default, every SSL connection curl makes is verified to be secure. This
@@ -13,4 +14,4 @@ The server connection is verified by making sure the server's certificate
contains the right name and verifies successfully using the cert store.
See this online resource for further details:
- https://curl.haxx.se/docs/sslcerts.html
+ https://curl.se/docs/sslcerts.html
diff --git a/docs/cmdline-opts/interface.d b/docs/cmdline-opts/interface.d
index 65827fb8b..196e7efa3 100644
--- a/docs/cmdline-opts/interface.d
+++ b/docs/cmdline-opts/interface.d
@@ -2,6 +2,7 @@ Long: interface
Arg: <name>
Help: Use network INTERFACE (or address)
See-also: dns-interface
+Category: connection
---
Perform an operation using a specified interface. You can enter interface
diff --git a/docs/cmdline-opts/ipv4.d b/docs/cmdline-opts/ipv4.d
index 9c40c8c3e..a6691376a 100644
--- a/docs/cmdline-opts/ipv4.d
+++ b/docs/cmdline-opts/ipv4.d
@@ -7,6 +7,7 @@ Mutexed: ipv6
Requires:
See-also: http1.1 http2
Help: Resolve names to IPv4 addresses
+Category: connection dns
---
This option tells curl to resolve names to IPv4 addresses only, and not for
example try IPv6.
diff --git a/docs/cmdline-opts/ipv6.d b/docs/cmdline-opts/ipv6.d
index 6eef6dd03..ce0415caa 100644
--- a/docs/cmdline-opts/ipv6.d
+++ b/docs/cmdline-opts/ipv6.d
@@ -7,6 +7,7 @@ Mutexed: ipv4
Requires:
See-also: http1.1 http2
Help: Resolve names to IPv6 addresses
+Category: connection dns
---
This option tells curl to resolve names to IPv6 addresses only, and not for
example try IPv4.
diff --git a/docs/cmdline-opts/junk-session-cookies.d b/docs/cmdline-opts/junk-session-cookies.d
index 40ccd9c2d..993b77fa8 100644
--- a/docs/cmdline-opts/junk-session-cookies.d
+++ b/docs/cmdline-opts/junk-session-cookies.d
@@ -3,6 +3,7 @@ Short: j
Help: Ignore session cookies read from file
Protocols: HTTP
See-also: cookie cookie-jar
+Category: http
---
When curl is told to read cookies from a given file, this option will make it
discard all "session cookies". This will basically have the same effect as if
diff --git a/docs/cmdline-opts/keepalive-time.d b/docs/cmdline-opts/keepalive-time.d
index c816e13ff..41261535c 100644
--- a/docs/cmdline-opts/keepalive-time.d
+++ b/docs/cmdline-opts/keepalive-time.d
@@ -2,6 +2,7 @@ Long: keepalive-time
Arg: <seconds>
Help: Interval time for keepalive probes
Added: 7.18.0
+Category: connection
---
This option sets the time a connection needs to remain idle before sending
keepalive probes and the time between individual keepalive probes. It is
diff --git a/docs/cmdline-opts/key-type.d b/docs/cmdline-opts/key-type.d
index bf39bcd35..50a068676 100644
--- a/docs/cmdline-opts/key-type.d
+++ b/docs/cmdline-opts/key-type.d
@@ -2,6 +2,7 @@ Long: key-type
Arg: <type>
Help: Private key file type (DER/PEM/ENG)
Protocols: TLS
+Category: tls
---
Private key file type. Specify which type your --key provided private key
is. DER, PEM, and ENG are supported. If not specified, PEM is assumed.
diff --git a/docs/cmdline-opts/key.d b/docs/cmdline-opts/key.d
index 855e2f7b6..a762e6faf 100644
--- a/docs/cmdline-opts/key.d
+++ b/docs/cmdline-opts/key.d
@@ -2,6 +2,7 @@ Long: key
Arg: <key>
Protocols: TLS SSH
Help: Private key file name
+Category: tls ssh
---
Private key file name. Allows you to provide your private key in this separate
file. For SSH, if not specified, curl tries the following candidates in order:
diff --git a/docs/cmdline-opts/krb.d b/docs/cmdline-opts/krb.d
index 19547af08..7759cfb04 100644
--- a/docs/cmdline-opts/krb.d
+++ b/docs/cmdline-opts/krb.d
@@ -3,6 +3,7 @@ Arg: <level>
Help: Enable Kerberos with security <level>
Protocols: FTP
Requires: Kerberos
+Category: ftp
---
Enable Kerberos authentication and use. The level must be entered and should
be one of 'clear', 'safe', 'confidential', or 'private'. Should you use a
diff --git a/docs/cmdline-opts/libcurl.d b/docs/cmdline-opts/libcurl.d
index ef132fe74..eb9850c68 100644
--- a/docs/cmdline-opts/libcurl.d
+++ b/docs/cmdline-opts/libcurl.d
@@ -2,6 +2,7 @@ Long: libcurl
Arg: <file>
Help: Dump libcurl equivalent code of this command line
Added: 7.16.1
+Category: curl
---
Append this option to any ordinary curl command line, and you will get a
libcurl-using C source code written to the file that does the equivalent
diff --git a/docs/cmdline-opts/limit-rate.d b/docs/cmdline-opts/limit-rate.d
index 06c456e3e..cb3a86077 100644
--- a/docs/cmdline-opts/limit-rate.d
+++ b/docs/cmdline-opts/limit-rate.d
@@ -1,6 +1,7 @@
Long: limit-rate
Arg: <speed>
Help: Limit transfer speed to RATE
+Category: connection
---
Specify the maximum transfer rate you want curl to use - for both downloads
and uploads. This feature is useful if you have a limited pipe and you'd like
diff --git a/docs/cmdline-opts/list-only.d b/docs/cmdline-opts/list-only.d
index 63b2851f4..c69885801 100644
--- a/docs/cmdline-opts/list-only.d
+++ b/docs/cmdline-opts/list-only.d
@@ -3,6 +3,7 @@ Short: l
Protocols: FTP POP3
Help: List only mode
Added: 4.0
+Category: ftp pop3
---
(FTP)
When listing an FTP directory, this switch forces a name-only view. This is
diff --git a/docs/cmdline-opts/local-port.d b/docs/cmdline-opts/local-port.d
index d96b46eb8..3f7a0e024 100644
--- a/docs/cmdline-opts/local-port.d
+++ b/docs/cmdline-opts/local-port.d
@@ -2,6 +2,7 @@ Long: local-port
Arg: <num/range>
Help: Force use of RANGE for local port numbers
Added: 7.15.2
+Category: connection
---
Set a preferred single number or range (FROM-TO) of local port numbers to use
for the connection(s). Note that port numbers by nature are a scarce resource
diff --git a/docs/cmdline-opts/location-trusted.d b/docs/cmdline-opts/location-trusted.d
index 995a8718a..f01d842bc 100644
--- a/docs/cmdline-opts/location-trusted.d
+++ b/docs/cmdline-opts/location-trusted.d
@@ -2,6 +2,7 @@ Long: location-trusted
Help: Like --location, and send auth to other hosts
Protocols: HTTP
See-also: user
+Category: http auth
---
Like --location, but will allow sending the name + password to all hosts that
the site may redirect to. This may or may not introduce a security breach if
diff --git a/docs/cmdline-opts/location.d b/docs/cmdline-opts/location.d
index b5ba1f4fa..c70b2eba8 100644
--- a/docs/cmdline-opts/location.d
+++ b/docs/cmdline-opts/location.d
@@ -2,6 +2,7 @@ Long: location
Short: L
Help: Follow redirects
Protocols: HTTP
+Category: http
---
If the server reports that the requested page has moved to a different
location (indicated with a Location: header and a 3XX response code), this
diff --git a/docs/cmdline-opts/login-options.d b/docs/cmdline-opts/login-options.d
index 8bad0511d..887d5d517 100644
--- a/docs/cmdline-opts/login-options.d
+++ b/docs/cmdline-opts/login-options.d
@@ -3,6 +3,7 @@ Arg: <options>
Protocols: IMAP POP3 SMTP
Help: Server login options
Added: 7.34.0
+Category: imap pop3 smtp auth
---
Specify the login options to use during server authentication.
diff --git a/docs/cmdline-opts/mail-auth.d b/docs/cmdline-opts/mail-auth.d
index 70cf0eda4..529997161 100644
--- a/docs/cmdline-opts/mail-auth.d
+++ b/docs/cmdline-opts/mail-auth.d
@@ -4,6 +4,7 @@ Protocols: SMTP
Help: Originator address of the original email
Added: 7.25.0
See-also: mail-rcpt mail-from
+Category: smtp
---
Specify a single address. This will be used to specify the authentication
address (identity) of a submitted message that is being relayed to another
diff --git a/docs/cmdline-opts/mail-from.d b/docs/cmdline-opts/mail-from.d
index 1d932344c..faf48e2a4 100644
--- a/docs/cmdline-opts/mail-from.d
+++ b/docs/cmdline-opts/mail-from.d
@@ -4,5 +4,6 @@ Help: Mail from this address
Protocols: SMTP
Added: 7.20.0
See-also: mail-rcpt mail-auth
+Category: smtp
---
Specify a single address that the given mail should get sent from.
diff --git a/docs/cmdline-opts/mail-rcpt-allowfails.d b/docs/cmdline-opts/mail-rcpt-allowfails.d
index b5723df34..76457c32e 100644
--- a/docs/cmdline-opts/mail-rcpt-allowfails.d
+++ b/docs/cmdline-opts/mail-rcpt-allowfails.d
@@ -2,6 +2,7 @@ Long: mail-rcpt-allowfails
Help: Allow RCPT TO command to fail for some recipients
Protocols: SMTP
Added: 7.69.0
+Category: smtp
---
When sending data to multiple recipients, by default curl will abort SMTP
conversation if at least one of the recipients causes RCPT TO command to
diff --git a/docs/cmdline-opts/mail-rcpt.d b/docs/cmdline-opts/mail-rcpt.d
index 0a2859b68..d8ae046ee 100644
--- a/docs/cmdline-opts/mail-rcpt.d
+++ b/docs/cmdline-opts/mail-rcpt.d
@@ -3,6 +3,7 @@ Arg: <address>
Help: Mail to this address
Protocols: SMTP
Added: 7.20.0
+Category: smtp
---
Specify a single address, user name or mailing list name. Repeat this
option several times to send to multiple recipients.
diff --git a/docs/cmdline-opts/manual.d b/docs/cmdline-opts/manual.d
index a9dbb0c78..25ed08dd2 100644
--- a/docs/cmdline-opts/manual.d
+++ b/docs/cmdline-opts/manual.d
@@ -1,5 +1,6 @@
Long: manual
Short: M
Help: Display the full manual
+Category: curl
---
Manual. Display the huge help text.
diff --git a/docs/cmdline-opts/max-filesize.d b/docs/cmdline-opts/max-filesize.d
index 50d5266e1..1f6bdc663 100644
--- a/docs/cmdline-opts/max-filesize.d
+++ b/docs/cmdline-opts/max-filesize.d
@@ -2,6 +2,7 @@ Long: max-filesize
Arg: <bytes>
Help: Maximum file size to download
See-also: limit-rate
+Category: connection
---
Specify the maximum size (in bytes) of a file to download. If the file
requested is larger than this value, the transfer will not start and curl will
diff --git a/docs/cmdline-opts/max-redirs.d b/docs/cmdline-opts/max-redirs.d
index a97860a8b..ba16c43fc 100644
--- a/docs/cmdline-opts/max-redirs.d
+++ b/docs/cmdline-opts/max-redirs.d
@@ -2,6 +2,7 @@ Long: max-redirs
Arg: <num>
Help: Maximum number of redirects allowed
Protocols: HTTP
+Category: http
---
Set maximum number of redirection-followings allowed. When --location is used,
is used to prevent curl from following redirections too much. By default, the
diff --git a/docs/cmdline-opts/max-time.d b/docs/cmdline-opts/max-time.d
index 0057f9d04..c4e4ed7eb 100644
--- a/docs/cmdline-opts/max-time.d
+++ b/docs/cmdline-opts/max-time.d
@@ -3,6 +3,7 @@ Short: m
Arg: <seconds>
Help: Maximum time allowed for the transfer
See-also: connect-timeout
+Category: connection
---
Maximum time in seconds that you allow the whole operation to take. This is
useful for preventing your batch jobs from hanging for hours due to slow
diff --git a/docs/cmdline-opts/metalink.d b/docs/cmdline-opts/metalink.d
index 81fc8bc78..883766439 100644
--- a/docs/cmdline-opts/metalink.d
+++ b/docs/cmdline-opts/metalink.d
@@ -2,6 +2,7 @@ Long: metalink
Help: Process given URLs as metalink XML file
Added: 7.27.0
Requires: metalink
+Category: misc
---
This option can tell curl to parse and process a given URI as Metalink file
(both version 3 and 4 (RFC 5854) are supported) and make use of the mirrors
diff --git a/docs/cmdline-opts/negotiate.d b/docs/cmdline-opts/negotiate.d
index 69a6b9170..e247bfbee 100644
--- a/docs/cmdline-opts/negotiate.d
+++ b/docs/cmdline-opts/negotiate.d
@@ -2,6 +2,7 @@ Long: negotiate
Help: Use HTTP Negotiate (SPNEGO) authentication
Protocols: HTTP
See-also: basic ntlm anyauth proxy-negotiate
+Category: auth http
---
Enables Negotiate (SPNEGO) authentication.
diff --git a/docs/cmdline-opts/netrc-file.d b/docs/cmdline-opts/netrc-file.d
index 50126d255..95fb2654a 100644
--- a/docs/cmdline-opts/netrc-file.d
+++ b/docs/cmdline-opts/netrc-file.d
@@ -3,6 +3,7 @@ Help: Specify FILE for netrc
Arg: <filename>
Added: 7.21.5
Mutexed: netrc
+Category: curl
---
This option is similar to --netrc, except that you provide the path (absolute
or relative) to the netrc file that curl should use. You can only specify one
diff --git a/docs/cmdline-opts/netrc-optional.d b/docs/cmdline-opts/netrc-optional.d
index c28540309..fa92032bd 100644
--- a/docs/cmdline-opts/netrc-optional.d
+++ b/docs/cmdline-opts/netrc-optional.d
@@ -2,6 +2,7 @@ Long: netrc-optional
Help: Use either .netrc or URL
Mutexed: netrc
See-also: netrc-file
+Category: curl
---
Very similar to --netrc, but this option makes the .netrc usage \fBoptional\fP
and not mandatory as the --netrc option does.
diff --git a/docs/cmdline-opts/netrc.d b/docs/cmdline-opts/netrc.d
index 2df26782c..6aac568a6 100644
--- a/docs/cmdline-opts/netrc.d
+++ b/docs/cmdline-opts/netrc.d
@@ -1,6 +1,7 @@
Long: netrc
Short: n
Help: Must read .netrc for user name and password
+Category: curl
---
Makes curl scan the \fI.netrc\fP (\fI_netrc\fP on Windows) file in the user's
home directory for login name and password. This is typically used for FTP on
diff --git a/docs/cmdline-opts/next.d b/docs/cmdline-opts/next.d
index 1d1e70a35..1adcc7535 100644
--- a/docs/cmdline-opts/next.d
+++ b/docs/cmdline-opts/next.d
@@ -5,6 +5,7 @@ Protocols:
Added: 7.36.0
Magic: divider
Help: Make next URL use its separate set of options
+Category: curl
---
Tells curl to use a separate operation for the following URL and associated
options. This allows you to send several URL requests, each with their own
diff --git a/docs/cmdline-opts/no-alpn.d b/docs/cmdline-opts/no-alpn.d
index 88abb8368..8031b4f07 100644
--- a/docs/cmdline-opts/no-alpn.d
+++ b/docs/cmdline-opts/no-alpn.d
@@ -5,6 +5,7 @@ Added: 7.36.0
See-also: no-npn http2
Requires: TLS
Help: Disable the ALPN TLS extension
+Category: tls http
---
Disable the ALPN TLS extension. ALPN is enabled by default if libcurl was built
with an SSL library that supports ALPN. ALPN is used by a libcurl that supports
diff --git a/docs/cmdline-opts/no-buffer.d b/docs/cmdline-opts/no-buffer.d
index 65a6282f6..1079f4712 100644
--- a/docs/cmdline-opts/no-buffer.d
+++ b/docs/cmdline-opts/no-buffer.d
@@ -1,6 +1,7 @@
Long: no-buffer
Short: N
Help: Disable buffering of the output stream
+Category: curl
---
Disables the buffering of the output stream. In normal work situations, curl
will use a standard buffered output stream that will have the effect that it
diff --git a/docs/cmdline-opts/no-keepalive.d b/docs/cmdline-opts/no-keepalive.d
index 8fb28a036..72f3bc9a5 100644
--- a/docs/cmdline-opts/no-keepalive.d
+++ b/docs/cmdline-opts/no-keepalive.d
@@ -1,5 +1,6 @@
Long: no-keepalive
Help: Disable TCP keepalive on the connection
+Category: connection
---
Disables the use of keepalive messages on the TCP connection. curl otherwise
enables them by default.
diff --git a/docs/cmdline-opts/no-npn.d b/docs/cmdline-opts/no-npn.d
index ab0f6de2e..27e5974bd 100644
--- a/docs/cmdline-opts/no-npn.d
+++ b/docs/cmdline-opts/no-npn.d
@@ -6,6 +6,7 @@ Mutexed:
See-also: no-alpn http2
Requires: TLS
Help: Disable the NPN TLS extension
+Category: tls http
---
Disable the NPN TLS extension. NPN is enabled by default if libcurl was built
with an SSL library that supports NPN. NPN is used by a libcurl that supports
diff --git a/docs/cmdline-opts/no-progress-meter.d b/docs/cmdline-opts/no-progress-meter.d
index aff0717d3..bf28d635d 100644
--- a/docs/cmdline-opts/no-progress-meter.d
+++ b/docs/cmdline-opts/no-progress-meter.d
@@ -2,6 +2,7 @@ Long: no-progress-meter
Help: Do not show the progress meter
See-also: verbose silent
Added: 7.67.0
+Category: verbose
---
Option to switch off the progress meter output without muting or otherwise
affecting warning and informational messages like --silent does.
diff --git a/docs/cmdline-opts/no-sessionid.d b/docs/cmdline-opts/no-sessionid.d
index 397a15869..013ca4cb4 100644
--- a/docs/cmdline-opts/no-sessionid.d
+++ b/docs/cmdline-opts/no-sessionid.d
@@ -2,6 +2,7 @@ Long: no-sessionid
Help: Disable SSL session-ID reusing
Protocols: TLS
Added: 7.16.0
+Category: tls
---
Disable curl's use of SSL session-ID caching. By default all transfers are
done using the cache. Note that while nothing should ever get hurt by
diff --git a/docs/cmdline-opts/noproxy.d b/docs/cmdline-opts/noproxy.d
index a216e75f4..12ce6d3ed 100644
--- a/docs/cmdline-opts/noproxy.d
+++ b/docs/cmdline-opts/noproxy.d
@@ -2,6 +2,7 @@ Long: noproxy
Arg: <no-proxy-list>
Help: List of hosts which do not use proxy
Added: 7.19.4
+Category: proxy
---
Comma-separated list of hosts which do not use a proxy, if one is specified.
The only wildcard is a single * character, which matches all hosts, and
diff --git a/docs/cmdline-opts/ntlm-wb.d b/docs/cmdline-opts/ntlm-wb.d
index 7b9338408..4a2f7e1e6 100644
--- a/docs/cmdline-opts/ntlm-wb.d
+++ b/docs/cmdline-opts/ntlm-wb.d
@@ -2,6 +2,7 @@ Long: ntlm-wb
Help: Use HTTP NTLM authentication with winbind
Protocols: HTTP
See-also: ntlm proxy-ntlm
+Category: auth http
---
Enables NTLM much in the style --ntlm does, but hand over the authentication
to the separate binary ntlmauth application that is executed when needed.
diff --git a/docs/cmdline-opts/ntlm.d b/docs/cmdline-opts/ntlm.d
index baaa1d534..c63c086eb 100644
--- a/docs/cmdline-opts/ntlm.d
+++ b/docs/cmdline-opts/ntlm.d
@@ -4,6 +4,7 @@ Mutexed: basic negotiate digest anyauth
See-also: proxy-ntlm
Protocols: HTTP
Requires: TLS
+Category: auth http
---
Enables NTLM authentication. The NTLM authentication method was designed by
Microsoft and is used by IIS web servers. It is a proprietary protocol,
diff --git a/docs/cmdline-opts/oauth2-bearer.d b/docs/cmdline-opts/oauth2-bearer.d
index 30466e579..e0ea210ed 100644
--- a/docs/cmdline-opts/oauth2-bearer.d
+++ b/docs/cmdline-opts/oauth2-bearer.d
@@ -2,6 +2,7 @@ Long: oauth2-bearer
Help: OAuth 2 Bearer Token
Arg: <token>
Protocols: IMAP POP3 SMTP HTTP
+Category: auth
---
Specify the Bearer Token for OAUTH 2.0 server authentication. The Bearer Token
is used in conjunction with the user name which can be specified as part of
diff --git a/docs/cmdline-opts/output-dir.d b/docs/cmdline-opts/output-dir.d
new file mode 100644
index 000000000..d2ff7738e
--- /dev/null
+++ b/docs/cmdline-opts/output-dir.d
@@ -0,0 +1,19 @@
+Long: output-dir
+Arg: <dir>
+Help: Directory to save files in
+Added: 7.73.0
+See-also: remote-name remote-header-name
+Category: curl
+---
+
+This option specifies the directory in which files should be stored, when
+--remote-name or --output are used.
+
+The given output directory is used for all URLs and output options on the
+command line, up until the first --next.
+
+If the specified target directory doesn't exist, the operation will fail
+unless --create-dirs is also used.
+
+If this option is used multiple times, the last specified directory will be
+used.
diff --git a/docs/cmdline-opts/output.d b/docs/cmdline-opts/output.d
index f310c267d..bf35bf4a0 100644
--- a/docs/cmdline-opts/output.d
+++ b/docs/cmdline-opts/output.d
@@ -3,6 +3,7 @@ Arg: <file>
Short: o
Help: Write to file instead of stdout
See-also: remote-name remote-name-all remote-header-name
+Category: important curl
---
Write output to <file> instead of stdout. If you are using {} or [] to fetch
multiple documents, you should quote the URL and you can use '#' followed by a
diff --git a/docs/cmdline-opts/page-footer b/docs/cmdline-opts/page-footer
index de77c4e0c..f105eb759 100644
--- a/docs/cmdline-opts/page-footer
+++ b/docs/cmdline-opts/page-footer
@@ -39,11 +39,15 @@ accesses the target URL through the proxy.
The list of host names can also be include numerical IP addresses, and IPv6
versions should then be given without enclosing brackets.
+IPv6 numerical addresses are compared as strings, so they will only match if
+the representations are the same: "::1" is the same as "::0:1" but they don't
+match.
+
.IP "CURL_SSL_BACKEND <TLS backend>"
If curl was built with support for "MultiSSL", meaning that it has built-in
support for more than one TLS backend, this environment variable can be set to
the case insensitive name of the particular backend to use when curl is
-invokved. Setting a name that isn't a built-in alternative, will make curl
+invoked. Setting a name that isn't a built-in alternative, will make curl
stay with the default.
.IP "QLOGDIR <directory name>"
If curl was built with HTTP/3 support, setting this environment variable to a
@@ -279,6 +283,6 @@ are meant to never change.
Daniel Stenberg is the main author, but the whole list of contributors is
found in the separate THANKS file.
.Sh SEE ALSO
-.Lk https://curl.haxx.se
+.Lk https://curl.se
.Xr ftp 1 ,
.Xr wget 1
diff --git a/docs/cmdline-opts/page-header b/docs/cmdline-opts/page-header
index a51e485ba..dcc299f73 100644
--- a/docs/cmdline-opts/page-header
+++ b/docs/cmdline-opts/page-header
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -99,6 +99,15 @@ getting many files from the same server will not do multiple connects /
handshakes. This improves speed. Of course this is only done on files
specified on a single command line and cannot be used between separate curl
invokes.
+.SH OUTPUT
+If not told otherwise, curl writes the received data to stdout. It can be
+instructed to instead save that data into a local file, using the --output or
+--remote-name options. If curl is given multiple URLs to transfer on the
+command line, it similarly needs multiple options for where to save them.
+
+curl does not parse or otherwise "understand" the content it gets or writes as
+output. It does no encoding or decoding, unless explicitly asked so with
+dedicated command line options.
.SH PROTOCOLS
curl supports numerous protocols, or put in URL terms: schemes. Your
particular build may not support them all.
diff --git a/docs/cmdline-opts/parallel-immediate.d b/docs/cmdline-opts/parallel-immediate.d
index 343931085..95c8afc42 100644
--- a/docs/cmdline-opts/parallel-immediate.d
+++ b/docs/cmdline-opts/parallel-immediate.d
@@ -2,6 +2,7 @@ Long: parallel-immediate
Help: Do not wait for multiplexing (with --parallel)
Added: 7.68.0
See-also: parallel parallel-max
+Category: connection curl
---
When doing parallel transfers, this option will instruct curl that it should
rather prefer opening up more connections in parallel at once rather than
diff --git a/docs/cmdline-opts/parallel-max.d b/docs/cmdline-opts/parallel-max.d
index a8c79c743..d49aeb7a9 100644
--- a/docs/cmdline-opts/parallel-max.d
+++ b/docs/cmdline-opts/parallel-max.d
@@ -2,6 +2,7 @@ Long: parallel-max
Help: Maximum concurrency for parallel transfers
Added: 7.66.0
See-also: parallel
+Category: connection curl
---
When asked to do parallel transfers, using --parallel, this option controls
the maximum amount of transfers to do simultaneously.
diff --git a/docs/cmdline-opts/parallel.d b/docs/cmdline-opts/parallel.d
index fac84e624..d6b4affe3 100644
--- a/docs/cmdline-opts/parallel.d
+++ b/docs/cmdline-opts/parallel.d
@@ -2,6 +2,7 @@ Short: Z
Long: parallel
Help: Perform transfers in parallel
Added: 7.66.0
+Category: connection curl
---
Makes curl perform its transfers in parallel as compared to the regular serial
manner.
diff --git a/docs/cmdline-opts/pass.d b/docs/cmdline-opts/pass.d
index 2639cb9d0..f6633d242 100644
--- a/docs/cmdline-opts/pass.d
+++ b/docs/cmdline-opts/pass.d
@@ -2,6 +2,7 @@ Long: pass
Arg: <phrase>
Help: Pass phrase for the private key
Protocols: SSH TLS
+Category: ssh tls auth
---
Passphrase for the private key
diff --git a/docs/cmdline-opts/path-as-is.d b/docs/cmdline-opts/path-as-is.d
index 946e2f07a..0bfaf6639 100644
--- a/docs/cmdline-opts/path-as-is.d
+++ b/docs/cmdline-opts/path-as-is.d
@@ -1,6 +1,7 @@
Long: path-as-is
Help: Do not squash .. sequences in URL path
Added: 7.42.0
+Category: curl
---
Tell curl to not handle sequences of /../ or /./ in the given URL
path. Normally curl will squash or merge them according to standards but with
diff --git a/docs/cmdline-opts/pinnedpubkey.d b/docs/cmdline-opts/pinnedpubkey.d
index cd21911f8..617252c6c 100644
--- a/docs/cmdline-opts/pinnedpubkey.d
+++ b/docs/cmdline-opts/pinnedpubkey.d
@@ -2,6 +2,7 @@ Long: pinnedpubkey
Arg: <hashes>
Help: FILE/HASHES Public key to verify peer against
Protocols: TLS
+Category: tls
---
Tells curl to use the specified public key file (or hashes) to verify the
peer. This can be a path to a file which contains a single public key in PEM
diff --git a/docs/cmdline-opts/post301.d b/docs/cmdline-opts/post301.d
index 87a9fe7ed..9cc2ad018 100644
--- a/docs/cmdline-opts/post301.d
+++ b/docs/cmdline-opts/post301.d
@@ -3,6 +3,7 @@ Help: Do not switch to GET after following a 301
Protocols: HTTP
See-also: post302 post303 location
Added: 7.17.1
+Category: http post
---
Tells curl to respect RFC 7231/6.4.2 and not convert POST requests into GET
requests when following a 301 redirection. The non-RFC behaviour is ubiquitous
diff --git a/docs/cmdline-opts/post302.d b/docs/cmdline-opts/post302.d
index caf0d87f1..02749032f 100644
--- a/docs/cmdline-opts/post302.d
+++ b/docs/cmdline-opts/post302.d
@@ -3,6 +3,7 @@ Help: Do not switch to GET after following a 302
Protocols: HTTP
See-also: post301 post303 location
Added: 7.19.1
+Category: http post
---
Tells curl to respect RFC 7231/6.4.3 and not convert POST requests into GET
requests when following a 302 redirection. The non-RFC behaviour is ubiquitous
diff --git a/docs/cmdline-opts/post303.d b/docs/cmdline-opts/post303.d
index 44f39e610..1a67e13ef 100644
--- a/docs/cmdline-opts/post303.d
+++ b/docs/cmdline-opts/post303.d
@@ -3,6 +3,7 @@ Help: Do not switch to GET after following a 303
Protocols: HTTP
See-also: post302 post301 location
Added: 7.26.0
+Category: http post
---
Tells curl to violate RFC 7231/6.4.4 and not convert POST requests into GET
requests when following 303 redirections. A server may require a POST to
diff --git a/docs/cmdline-opts/preproxy.d b/docs/cmdline-opts/preproxy.d
index b8eb77fa4..a917c16ed 100644
--- a/docs/cmdline-opts/preproxy.d
+++ b/docs/cmdline-opts/preproxy.d
@@ -2,6 +2,7 @@ Long: preproxy
Arg: [protocol://]host[:port]
Help: Use this proxy first
Added: 7.52.0
+Category: proxy
---
Use the specified SOCKS proxy before connecting to an HTTP or HTTPS --proxy. In
such a case curl first connects to the SOCKS proxy and then connects (through
diff --git a/docs/cmdline-opts/progress-bar.d b/docs/cmdline-opts/progress-bar.d
index f27de2d93..299d5384a 100644
--- a/docs/cmdline-opts/progress-bar.d
+++ b/docs/cmdline-opts/progress-bar.d
@@ -1,6 +1,7 @@
Short: #
Long: progress-bar
Help: Display transfer progress as a bar
+Category: verbose
---
Make curl display transfer progress as a simple progress bar instead of the
standard, more informational, meter.
diff --git a/docs/cmdline-opts/proto-default.d b/docs/cmdline-opts/proto-default.d
index ccc3b85f3..1c2afea2c 100644
--- a/docs/cmdline-opts/proto-default.d
+++ b/docs/cmdline-opts/proto-default.d
@@ -2,6 +2,7 @@ Long: proto-default
Help: Use PROTOCOL for any URL missing a scheme
Arg: <protocol>
Added: 7.45.0
+Category: connection curl
---
Tells curl to use \fIprotocol\fP for any URL missing a scheme name.
diff --git a/docs/cmdline-opts/proto-redir.d b/docs/cmdline-opts/proto-redir.d
index a1205dd03..9a096f531 100644
--- a/docs/cmdline-opts/proto-redir.d
+++ b/docs/cmdline-opts/proto-redir.d
@@ -2,6 +2,7 @@ Long: proto-redir
Arg: <protocols>
Help: Enable/disable PROTOCOLS on redirect
Added: 7.20.2
+Category: connection curl
---
Tells curl to limit what protocols it may use on redirect. Protocols denied by
--proto are not overridden by this option. See --proto for how protocols are
diff --git a/docs/cmdline-opts/proto.d b/docs/cmdline-opts/proto.d
index e1ece1788..46c912254 100644
--- a/docs/cmdline-opts/proto.d
+++ b/docs/cmdline-opts/proto.d
@@ -3,6 +3,7 @@ Arg: <protocols>
Help: Enable/disable PROTOCOLS
See-also: proto-redir proto-default
Added: 7.20.2
+Category: connection curl
---
Tells curl to limit what protocols it may use in the transfer. Protocols are
evaluated left to right, are comma separated, and are each a protocol name or
diff --git a/docs/cmdline-opts/proxy-anyauth.d b/docs/cmdline-opts/proxy-anyauth.d
index b60d0a05e..6410c0e6a 100644
--- a/docs/cmdline-opts/proxy-anyauth.d
+++ b/docs/cmdline-opts/proxy-anyauth.d
@@ -2,6 +2,7 @@ Long: proxy-anyauth
Help: Pick any proxy authentication method
Added: 7.13.2
See-also: proxy proxy-basic proxy-digest
+Category: proxy auth
---
Tells curl to pick a suitable authentication method when communicating with
the given HTTP proxy. This might cause an extra request/response round-trip.
diff --git a/docs/cmdline-opts/proxy-basic.d b/docs/cmdline-opts/proxy-basic.d
index 566f890a9..e842f9900 100644
--- a/docs/cmdline-opts/proxy-basic.d
+++ b/docs/cmdline-opts/proxy-basic.d
@@ -1,6 +1,7 @@
Long: proxy-basic
Help: Use Basic authentication on the proxy
See-also: proxy proxy-anyauth proxy-digest
+Category: proxy auth
---
Tells curl to use HTTP Basic authentication when communicating with the given
proxy. Use --basic for enabling HTTP Basic with a remote host. Basic is the
diff --git a/docs/cmdline-opts/proxy-cacert.d b/docs/cmdline-opts/proxy-cacert.d
index 2713dd2a4..bbc731a28 100644
--- a/docs/cmdline-opts/proxy-cacert.d
+++ b/docs/cmdline-opts/proxy-cacert.d
@@ -3,5 +3,6 @@ Help: CA certificate to verify peer against for proxy
Arg: <file>
Added: 7.52.0
See-also: proxy-capath cacert capath proxy
+Category: proxy tls
---
Same as --cacert but used in HTTPS proxy context.
diff --git a/docs/cmdline-opts/proxy-capath.d b/docs/cmdline-opts/proxy-capath.d
index 177246aab..cc342b755 100644
--- a/docs/cmdline-opts/proxy-capath.d
+++ b/docs/cmdline-opts/proxy-capath.d
@@ -3,5 +3,6 @@ Help: CA directory to verify peer against for proxy
Arg: <dir>
Added: 7.52.0
See-also: proxy-cacert proxy capath
+Category: proxy tls
---
Same as --capath but used in HTTPS proxy context.
diff --git a/docs/cmdline-opts/proxy-cert-type.d b/docs/cmdline-opts/proxy-cert-type.d
index 906d2a115..fb7596c17 100644
--- a/docs/cmdline-opts/proxy-cert-type.d
+++ b/docs/cmdline-opts/proxy-cert-type.d
@@ -2,5 +2,6 @@ Long: proxy-cert-type
Arg: <type>
Added: 7.52.0
Help: Client certificate type for HTTPS proxy
+Category: proxy tls
---
Same as --cert-type but used in HTTPS proxy context.
diff --git a/docs/cmdline-opts/proxy-cert.d b/docs/cmdline-opts/proxy-cert.d
index 43acd3950..7df2712f3 100644
--- a/docs/cmdline-opts/proxy-cert.d
+++ b/docs/cmdline-opts/proxy-cert.d
@@ -2,5 +2,6 @@ Long: proxy-cert
Arg: <cert[:passwd]>
Help: Set client certificate for proxy
Added: 7.52.0
+Category: proxy tls
---
Same as --cert but used in HTTPS proxy context.
diff --git a/docs/cmdline-opts/proxy-ciphers.d b/docs/cmdline-opts/proxy-ciphers.d
index dcac81284..366555673 100644
--- a/docs/cmdline-opts/proxy-ciphers.d
+++ b/docs/cmdline-opts/proxy-ciphers.d
@@ -2,5 +2,6 @@ Long: proxy-ciphers
Arg: <list>
Help: SSL ciphers to use for proxy
Added: 7.52.0
+Category: proxy tls
---
Same as --ciphers but used in HTTPS proxy context.
diff --git a/docs/cmdline-opts/proxy-crlfile.d b/docs/cmdline-opts/proxy-crlfile.d
index 1d6247f47..580dc50ce 100644
--- a/docs/cmdline-opts/proxy-crlfile.d
+++ b/docs/cmdline-opts/proxy-crlfile.d
@@ -2,5 +2,6 @@ Long: proxy-crlfile
Arg: <file>
Help: Set a CRL list for proxy
Added: 7.52.0
+Category: proxy tls
---
Same as --crlfile but used in HTTPS proxy context.
diff --git a/docs/cmdline-opts/proxy-digest.d b/docs/cmdline-opts/proxy-digest.d
index ccf46636c..52f1fcc67 100644
--- a/docs/cmdline-opts/proxy-digest.d
+++ b/docs/cmdline-opts/proxy-digest.d
@@ -1,6 +1,7 @@
Long: proxy-digest
Help: Use Digest authentication on the proxy
See-also: proxy proxy-anyauth proxy-basic
+Category: proxy tls
---
Tells curl to use HTTP Digest authentication when communicating with the given
proxy. Use --digest for enabling HTTP Digest with a remote host.
diff --git a/docs/cmdline-opts/proxy-header.d b/docs/cmdline-opts/proxy-header.d
index c1b0bb7c4..9f1121d2f 100644
--- a/docs/cmdline-opts/proxy-header.d
+++ b/docs/cmdline-opts/proxy-header.d
@@ -3,6 +3,7 @@ Arg: <header/@file>
Help: Pass custom header(s) to proxy
Protocols: HTTP
Added: 7.37.0
+Category: proxy
---
Extra header to include in the request when sending HTTP to a proxy. You may
specify any number of extra headers. This is the equivalent option to --header
diff --git a/docs/cmdline-opts/proxy-insecure.d b/docs/cmdline-opts/proxy-insecure.d
index 762828f43..e123f4019 100644
--- a/docs/cmdline-opts/proxy-insecure.d
+++ b/docs/cmdline-opts/proxy-insecure.d
@@ -1,5 +1,6 @@
Long: proxy-insecure
Help: Do HTTPS proxy connections without verifying the proxy
Added: 7.52.0
+Category: proxy tls
---
Same as --insecure but used in HTTPS proxy context.
diff --git a/docs/cmdline-opts/proxy-key-type.d b/docs/cmdline-opts/proxy-key-type.d
index ce7482ae9..1906872ef 100644
--- a/docs/cmdline-opts/proxy-key-type.d
+++ b/docs/cmdline-opts/proxy-key-type.d
@@ -2,5 +2,6 @@ Long: proxy-key-type
Arg: <type>
Help: Private key file type for proxy
Added: 7.52.0
+Category: proxy tls
---
Same as --key-type but used in HTTPS proxy context.
diff --git a/docs/cmdline-opts/proxy-key.d b/docs/cmdline-opts/proxy-key.d
index e61eb18a9..57d469f43 100644
--- a/docs/cmdline-opts/proxy-key.d
+++ b/docs/cmdline-opts/proxy-key.d
@@ -1,5 +1,6 @@
Long: proxy-key
Help: Private key for HTTPS proxy
Arg: <key>
+Category: proxy tls
---
Same as --key but used in HTTPS proxy context.
diff --git a/docs/cmdline-opts/proxy-negotiate.d b/docs/cmdline-opts/proxy-negotiate.d
index 775f62a9a..72f35960e 100644
--- a/docs/cmdline-opts/proxy-negotiate.d
+++ b/docs/cmdline-opts/proxy-negotiate.d
@@ -2,6 +2,7 @@ Long: proxy-negotiate
Help: Use HTTP Negotiate (SPNEGO) authentication on the proxy
Added: 7.17.1
See-also: proxy-anyauth proxy-basic
+Category: proxy auth
---
Tells curl to use HTTP Negotiate (SPNEGO) authentication when communicating
with the given proxy. Use --negotiate for enabling HTTP Negotiate (SPNEGO)
diff --git a/docs/cmdline-opts/proxy-ntlm.d b/docs/cmdline-opts/proxy-ntlm.d
index c30db53b9..cb1ba7b00 100644
--- a/docs/cmdline-opts/proxy-ntlm.d
+++ b/docs/cmdline-opts/proxy-ntlm.d
@@ -1,6 +1,7 @@
Long: proxy-ntlm
Help: Use NTLM authentication on the proxy
See-also: proxy-negotiate proxy-anyauth
+Category: proxy auth
---
Tells curl to use HTTP NTLM authentication when communicating with the given
proxy. Use --ntlm for enabling NTLM with a remote host.
diff --git a/docs/cmdline-opts/proxy-pass.d b/docs/cmdline-opts/proxy-pass.d
index 3371714ba..627451bbb 100644
--- a/docs/cmdline-opts/proxy-pass.d
+++ b/docs/cmdline-opts/proxy-pass.d
@@ -2,5 +2,6 @@ Long: proxy-pass
Arg: <phrase>
Help: Pass phrase for the private key for HTTPS proxy
Added: 7.52.0
+Category: proxy tls auth
---
Same as --pass but used in HTTPS proxy context.
diff --git a/docs/cmdline-opts/proxy-pinnedpubkey.d b/docs/cmdline-opts/proxy-pinnedpubkey.d
index abd6dc4aa..2ab79f19e 100644
--- a/docs/cmdline-opts/proxy-pinnedpubkey.d
+++ b/docs/cmdline-opts/proxy-pinnedpubkey.d
@@ -2,6 +2,7 @@ Long: proxy-pinnedpubkey
Arg: <hashes>
Help: FILE/HASHES public key to verify proxy with
Protocols: TLS
+Category: proxy tls
---
Tells curl to use the specified public key file (or hashes) to verify the
proxy. This can be a path to a file which contains a single public key in PEM
diff --git a/docs/cmdline-opts/proxy-service-name.d b/docs/cmdline-opts/proxy-service-name.d
index 9a73f2be6..f78072906 100644
--- a/docs/cmdline-opts/proxy-service-name.d
+++ b/docs/cmdline-opts/proxy-service-name.d
@@ -2,5 +2,6 @@ Long: proxy-service-name
Arg: <name>
Help: SPNEGO proxy service name
Added: 7.43.0
+Category: proxy tls
---
This option allows you to change the service name for proxy negotiation.
diff --git a/docs/cmdline-opts/proxy-ssl-allow-beast.d b/docs/cmdline-opts/proxy-ssl-allow-beast.d
index de96b8436..138001b36 100644
--- a/docs/cmdline-opts/proxy-ssl-allow-beast.d
+++ b/docs/cmdline-opts/proxy-ssl-allow-beast.d
@@ -1,5 +1,6 @@
Long: proxy-ssl-allow-beast
Help: Allow security flaw for interop for HTTPS proxy
Added: 7.52.0
+Category: proxy tls
---
Same as --ssl-allow-beast but used in HTTPS proxy context.
diff --git a/docs/cmdline-opts/proxy-tls13-ciphers.d b/docs/cmdline-opts/proxy-tls13-ciphers.d
index 08961b72e..9f03f135e 100644
--- a/docs/cmdline-opts/proxy-tls13-ciphers.d
+++ b/docs/cmdline-opts/proxy-tls13-ciphers.d
@@ -2,12 +2,13 @@ Long: proxy-tls13-ciphers
Arg: <ciphersuite list>
help: TLS 1.3 proxy cipher suites
Protocols: TLS
+Category: proxy tls
---
Specifies which cipher suites to use in the connection to your HTTPS proxy
when it negotiates TLS 1.3. The list of ciphers suites must specify valid
ciphers. Read up on TLS 1.3 cipher suite details on this URL:
- https://curl.haxx.se/docs/ssl-ciphers.html
+ https://curl.se/docs/ssl-ciphers.html
This option is currently used only when curl is built to use OpenSSL 1.1.1 or
later. If you are using a different SSL backend you can try setting TLS 1.3
diff --git a/docs/cmdline-opts/proxy-tlsauthtype.d b/docs/cmdline-opts/proxy-tlsauthtype.d
index 7d0ce8e1a..5649a0f5f 100644
--- a/docs/cmdline-opts/proxy-tlsauthtype.d
+++ b/docs/cmdline-opts/proxy-tlsauthtype.d
@@ -2,5 +2,6 @@ Long: proxy-tlsauthtype
Arg: <type>
Help: TLS authentication type for HTTPS proxy
Added: 7.52.0
+Category: proxy tls auth
---
Same as --tlsauthtype but used in HTTPS proxy context.
diff --git a/docs/cmdline-opts/proxy-tlspassword.d b/docs/cmdline-opts/proxy-tlspassword.d
index cf003844e..38a33d45d 100644
--- a/docs/cmdline-opts/proxy-tlspassword.d
+++ b/docs/cmdline-opts/proxy-tlspassword.d
@@ -2,5 +2,6 @@ Long: proxy-tlspassword
Arg: <string>
Help: TLS password for HTTPS proxy
Added: 7.52.0
+Category: proxy tls auth
---
Same as --tlspassword but used in HTTPS proxy context.
diff --git a/docs/cmdline-opts/proxy-tlsuser.d b/docs/cmdline-opts/proxy-tlsuser.d
index 758a7c953..587f7f510 100644
--- a/docs/cmdline-opts/proxy-tlsuser.d
+++ b/docs/cmdline-opts/proxy-tlsuser.d
@@ -2,5 +2,6 @@ Long: proxy-tlsuser
Arg: <name>
Help: TLS username for HTTPS proxy
Added: 7.52.0
+Category: proxy tls auth
---
Same as --tlsuser but used in HTTPS proxy context.
diff --git a/docs/cmdline-opts/proxy-tlsv1.d b/docs/cmdline-opts/proxy-tlsv1.d
index d024eeac3..5003f5f70 100644
--- a/docs/cmdline-opts/proxy-tlsv1.d
+++ b/docs/cmdline-opts/proxy-tlsv1.d
@@ -1,5 +1,6 @@
Long: proxy-tlsv1
Help: Use TLSv1 for HTTPS proxy
Added: 7.52.0
+Category: proxy tls auth
---
Same as --tlsv1 but used in HTTPS proxy context.
diff --git a/docs/cmdline-opts/proxy-user.d b/docs/cmdline-opts/proxy-user.d
index 152466daa..82fc5170f 100644
--- a/docs/cmdline-opts/proxy-user.d
+++ b/docs/cmdline-opts/proxy-user.d
@@ -2,6 +2,7 @@ Long: proxy-user
Short: U
Arg: <user:password>
Help: Proxy user and password
+Category: proxy auth
---
Specify the user name and password to use for proxy authentication.
diff --git a/docs/cmdline-opts/proxy.d b/docs/cmdline-opts/proxy.d
index 6506692be..0592f13ba 100644
--- a/docs/cmdline-opts/proxy.d
+++ b/docs/cmdline-opts/proxy.d
@@ -2,6 +2,7 @@ Long: proxy
Short: x
Arg: [protocol://]host[:port]
Help: Use this proxy
+Category: proxy
---
Use the specified proxy.
diff --git a/docs/cmdline-opts/proxy1.0.d b/docs/cmdline-opts/proxy1.0.d
index 4a931bd15..b8a232bf7 100644
--- a/docs/cmdline-opts/proxy1.0.d
+++ b/docs/cmdline-opts/proxy1.0.d
@@ -1,6 +1,7 @@
Long: proxy1.0
Arg: <host[:port]>
Help: Use HTTP/1.0 proxy on given port
+Category: proxy
---
Use the specified HTTP 1.0 proxy. If the port number is not specified, it is
assumed at port 1080.
diff --git a/docs/cmdline-opts/proxytunnel.d b/docs/cmdline-opts/proxytunnel.d
index 1f587f120..94dae992f 100644
--- a/docs/cmdline-opts/proxytunnel.d
+++ b/docs/cmdline-opts/proxytunnel.d
@@ -2,6 +2,7 @@ Long: proxytunnel
Short: p
Help: Operate through an HTTP proxy tunnel (using CONNECT)
See-also: proxy
+Category: proxy
---
When an HTTP proxy is used --proxy, this option will make curl tunnel through
the proxy. The tunnel approach is made with the HTTP proxy CONNECT request and
diff --git a/docs/cmdline-opts/pubkey.d b/docs/cmdline-opts/pubkey.d
index b2e11c024..692daf6b0 100644
--- a/docs/cmdline-opts/pubkey.d
+++ b/docs/cmdline-opts/pubkey.d
@@ -2,6 +2,7 @@ Long: pubkey
Arg: <key>
Protocols: SFTP SCP
Help: SSH Public key file name
+Category: sftp scp auth
---
Public key file name. Allows you to provide your public key in this separate
file.
diff --git a/docs/cmdline-opts/quote.d b/docs/cmdline-opts/quote.d
index 59a98eafb..a33ed3571 100644
--- a/docs/cmdline-opts/quote.d
+++ b/docs/cmdline-opts/quote.d
@@ -2,6 +2,7 @@ Long: quote
Short: Q
Help: Send command(s) to server before transfer
Protocols: FTP SFTP
+Category: ftp sftp
---
Send an arbitrary command to the remote FTP or SFTP server. Quote commands are
@@ -26,6 +27,10 @@ itself before sending them to the server. File names may be quoted
shell-style to embed spaces or special characters. Following is the list of
all supported SFTP quote commands:
.RS
+.IP "atime date file"
+The atime command sets the last access time of the file named by the file
+operand. The <date expression> can be all sorts of date strings, see the
+\fIcurl_getdate(3)\fP man page for date expression details. (Added in 7.73.0)
.IP "chgrp group file"
The chgrp command sets the group ID of the file named by the file operand to
the group ID specified by the group operand. The group operand is a decimal
@@ -42,6 +47,10 @@ The ln and symlink commands create a symbolic link at the target_file location
pointing to the source_file location.
.IP "mkdir directory_name"
The mkdir command creates the directory named by the directory_name operand.
+.IP "mtime date file"
+The mtime command sets the last modification time of the file named by the
+file operand. The <date expression> can be all sorts of date strings, see the
+\fIcurl_getdate(3)\fP man page for date expression details. (Added in 7.73.0)
.IP "pwd"
The pwd command returns the absolute pathname of the current working directory.
.IP "rename source target"
diff --git a/docs/cmdline-opts/random-file.d b/docs/cmdline-opts/random-file.d
index 51626f88d..c57f52364 100644
--- a/docs/cmdline-opts/random-file.d
+++ b/docs/cmdline-opts/random-file.d
@@ -1,6 +1,7 @@
Long: random-file
Arg: <file>
Help: File for reading random data from
+Category: misc
---
Specify the path name to file containing what will be considered as random
data. The data may be used to seed the random engine for SSL connections. See
diff --git a/docs/cmdline-opts/range.d b/docs/cmdline-opts/range.d
index b888dd181..e2d1f62fc 100644
--- a/docs/cmdline-opts/range.d
+++ b/docs/cmdline-opts/range.d
@@ -3,6 +3,7 @@ Short: r
Help: Retrieve only the bytes within RANGE
Arg: <range>
Protocols: HTTP FTP SFTP FILE
+Category: http ftp sftp file
---
Retrieve a byte range (i.e. a partial document) from an HTTP/1.1, FTP or SFTP
server or a local FILE. Ranges can be specified in a number of ways.
@@ -28,7 +29,8 @@ specifies two separate 100-byte ranges(*) (HTTP)
.RE
.IP
(*) = NOTE that this will cause the server to reply with a multipart
-response!
+response, which will be returned as-is by curl! Parsing or otherwise
+transforming this response is the responsibility of the caller.
Only digit characters (0-9) are valid in the 'start' and 'stop' fields of the
\&'start-stop' range syntax. If a non-digit character is given in the range,
diff --git a/docs/cmdline-opts/raw.d b/docs/cmdline-opts/raw.d
index c3328e69a..90e777263 100644
--- a/docs/cmdline-opts/raw.d
+++ b/docs/cmdline-opts/raw.d
@@ -2,6 +2,7 @@ Long: raw
Help: Do HTTP "raw"; no transfer decoding
Added: 7.16.2
Protocols: HTTP
+Category: http
---
When used, it disables all internal HTTP decoding of content or transfer
encodings and instead makes them passed on unaltered, raw.
diff --git a/docs/cmdline-opts/referer.d b/docs/cmdline-opts/referer.d
index cd84e9d5a..8b2057b94 100644
--- a/docs/cmdline-opts/referer.d
+++ b/docs/cmdline-opts/referer.d
@@ -4,6 +4,7 @@ Arg: <URL>
Protocols: HTTP
Help: Referrer URL
See-also: user-agent header
+Category: http
---
Sends the "Referrer Page" information to the HTTP server. This can also be set
with the --header flag of course. When used with --location you can append
diff --git a/docs/cmdline-opts/remote-header-name.d b/docs/cmdline-opts/remote-header-name.d
index 771b6d469..700da69fc 100644
--- a/docs/cmdline-opts/remote-header-name.d
+++ b/docs/cmdline-opts/remote-header-name.d
@@ -2,6 +2,7 @@ Long: remote-header-name
Short: J
Protocols: HTTP
Help: Use the header-provided filename
+Category: output
---
This option tells the --remote-name option to use the server-specified
Content-Disposition filename instead of extracting a filename from the URL.
diff --git a/docs/cmdline-opts/remote-name-all.d b/docs/cmdline-opts/remote-name-all.d
index f7a199679..299684c51 100644
--- a/docs/cmdline-opts/remote-name-all.d
+++ b/docs/cmdline-opts/remote-name-all.d
@@ -1,6 +1,7 @@
Long: remote-name-all
Help: Use the remote file name for all URLs
Added: 7.19.0
+Category: output
---
This option changes the default action for all given URLs to be dealt with as
if --remote-name were used for each one. So if you want to disable that for a
diff --git a/docs/cmdline-opts/remote-name.d b/docs/cmdline-opts/remote-name.d
index 9fed64bf4..184c32e47 100644
--- a/docs/cmdline-opts/remote-name.d
+++ b/docs/cmdline-opts/remote-name.d
@@ -1,6 +1,7 @@
Long: remote-name
Short: O
Help: Write output to a file named as the remote file
+Category: important output
---
Write output to a local file named like the remote file we get. (Only the file
part of the remote file is used, the path is cut off.)
diff --git a/docs/cmdline-opts/remote-time.d b/docs/cmdline-opts/remote-time.d
index 7f6809dc3..96fb4fbe9 100644
--- a/docs/cmdline-opts/remote-time.d
+++ b/docs/cmdline-opts/remote-time.d
@@ -1,6 +1,7 @@
Long: remote-time
Short: R
Help: Set the remote file's time on the local output
+Category: output
---
When used, this will make curl attempt to figure out the timestamp of the
remote file, and if that is available make the local file get that same
diff --git a/docs/cmdline-opts/request-target.d b/docs/cmdline-opts/request-target.d
index b46b4af02..df423f87d 100644
--- a/docs/cmdline-opts/request-target.d
+++ b/docs/cmdline-opts/request-target.d
@@ -2,6 +2,7 @@ Long: request-target
Help: Specify the target for this request
Protocols: HTTP
Added: 7.55.0
+Category: http
---
Tells curl to use an alternative "target" (path) instead of using the path as
provided in the URL. Particularly useful when wanting to issue HTTP requests
diff --git a/docs/cmdline-opts/request.d b/docs/cmdline-opts/request.d
index 3919d426a..47c4c8b04 100644
--- a/docs/cmdline-opts/request.d
+++ b/docs/cmdline-opts/request.d
@@ -2,6 +2,7 @@ Long: request
Short: X
Arg: <command>
Help: Specify request command to use
+Category: connection
---
(HTTP) Specifies a custom request method to use when communicating with the
HTTP server. The specified request method will be used instead of the method
diff --git a/docs/cmdline-opts/resolve.d b/docs/cmdline-opts/resolve.d
index c1692f0f8..41f6a1bd5 100644
--- a/docs/cmdline-opts/resolve.d
+++ b/docs/cmdline-opts/resolve.d
@@ -2,6 +2,7 @@ Long: resolve
Arg: <host:port:addr[,addr]...>
Help: Resolve the host+port to this address
Added: 7.21.3
+Category: connection
---
Provide a custom address for a specific host and port pair. Using this, you
can make the curl requests(s) use a specified address and prevent the
diff --git a/docs/cmdline-opts/retry-all-errors.d b/docs/cmdline-opts/retry-all-errors.d
index 4554f5938..6bda52b6e 100644
--- a/docs/cmdline-opts/retry-all-errors.d
+++ b/docs/cmdline-opts/retry-all-errors.d
@@ -1,6 +1,7 @@
Long: retry-all-errors
Help: Retry all errors (use with --retry)
Added: 7.71.0
+Category: curl
---
Retry on any error. This option is used together with --retry.
diff --git a/docs/cmdline-opts/retry-connrefused.d b/docs/cmdline-opts/retry-connrefused.d
index 6a78e1fda..be34f973d 100644
--- a/docs/cmdline-opts/retry-connrefused.d
+++ b/docs/cmdline-opts/retry-connrefused.d
@@ -1,6 +1,7 @@
Long: retry-connrefused
Help: Retry on connection refused (use with --retry)
Added: 7.52.0
+Category: curl
---
In addition to the other conditions, consider ECONNREFUSED as a transient
error too for --retry. This option is used together with --retry.
diff --git a/docs/cmdline-opts/retry-delay.d b/docs/cmdline-opts/retry-delay.d
index 1691356d4..5645c0e6a 100644
--- a/docs/cmdline-opts/retry-delay.d
+++ b/docs/cmdline-opts/retry-delay.d
@@ -2,6 +2,7 @@ Long: retry-delay
Arg: <seconds>
Help: Wait time between retries
Added: 7.12.3
+Category: curl
---
Make curl sleep this amount of time before each retry when a transfer has
failed with a transient error (it changes the default backoff time algorithm
diff --git a/docs/cmdline-opts/retry-max-time.d b/docs/cmdline-opts/retry-max-time.d
index 0920c9244..9d6faf304 100644
--- a/docs/cmdline-opts/retry-max-time.d
+++ b/docs/cmdline-opts/retry-max-time.d
@@ -2,6 +2,7 @@ Long: retry-max-time
Arg: <seconds>
Help: Retry only within this period
Added: 7.12.3
+Category: curl
---
The retry timer is reset before the first transfer attempt. Retries will be
done as usual (see --retry) as long as the timer hasn't reached this given
diff --git a/docs/cmdline-opts/retry.d b/docs/cmdline-opts/retry.d
index 3db89b71c..70f6e7bfd 100644
--- a/docs/cmdline-opts/retry.d
+++ b/docs/cmdline-opts/retry.d
@@ -2,6 +2,7 @@ Long: retry
Arg: <num>
Added: 7.12.3
Help: Retry request if transient problems occur
+Category: curl
---
If a transient error is returned when curl tries to perform a transfer, it
will retry this number of times before giving up. Setting the number to 0
diff --git a/docs/cmdline-opts/sasl-authzid.d b/docs/cmdline-opts/sasl-authzid.d
index a3bd46e70..e802c80a1 100644
--- a/docs/cmdline-opts/sasl-authzid.d
+++ b/docs/cmdline-opts/sasl-authzid.d
@@ -2,6 +2,7 @@ Long: sasl-authzid
Arg: <identity>
Help: Identity for SASL PLAIN authentication
Added: 7.66.0
+Category: auth
---
Use this authorisation identity (authzid), during SASL PLAIN authentication,
in addition to the authentication identity (authcid) as specified by --user.
diff --git a/docs/cmdline-opts/sasl-ir.d b/docs/cmdline-opts/sasl-ir.d
index c0dab9463..0041c3b4e 100644
--- a/docs/cmdline-opts/sasl-ir.d
+++ b/docs/cmdline-opts/sasl-ir.d
@@ -1,5 +1,6 @@
Long: sasl-ir
Help: Enable initial response in SASL authentication
Added: 7.31.0
+Category: auth
---
Enable initial response in SASL authentication.
diff --git a/docs/cmdline-opts/service-name.d b/docs/cmdline-opts/service-name.d
index 4dfeb27d6..c64496b85 100644
--- a/docs/cmdline-opts/service-name.d
+++ b/docs/cmdline-opts/service-name.d
@@ -2,6 +2,7 @@ Long: service-name
Help: SPNEGO service name
Arg: <name>
Added: 7.43.0
+Category: misc
---
This option allows you to change the service name for SPNEGO.
diff --git a/docs/cmdline-opts/show-error.d b/docs/cmdline-opts/show-error.d
index b9667a4ca..2124409e5 100644
--- a/docs/cmdline-opts/show-error.d
+++ b/docs/cmdline-opts/show-error.d
@@ -1,5 +1,7 @@
Long: show-error
Short: S
Help: Show error even when -s is used
+See-also: no-progress-meter
+Category: curl
---
When used with --silent, it makes curl show an error message if it fails.
diff --git a/docs/cmdline-opts/silent.d b/docs/cmdline-opts/silent.d
index b0b4425b3..58a522335 100644
--- a/docs/cmdline-opts/silent.d
+++ b/docs/cmdline-opts/silent.d
@@ -1,7 +1,8 @@
Long: silent
Short: s
Help: Silent mode
-See-also: verbose stderr
+See-also: verbose stderr no-progress-meter
+Category: important verbose
---
Silent or quiet mode. Don't show progress meter or error messages. Makes Curl
mute. It will still output the data you ask for, potentially even to the
diff --git a/docs/cmdline-opts/socks4.d b/docs/cmdline-opts/socks4.d
index 11f6ae033..bc095d546 100644
--- a/docs/cmdline-opts/socks4.d
+++ b/docs/cmdline-opts/socks4.d
@@ -2,6 +2,7 @@ Long: socks4
Arg: <host[:port]>
Help: SOCKS4 proxy on given host + port
Added: 7.15.2
+Category: proxy
---
Use the specified SOCKS4 proxy. If the port number is not specified, it is
assumed at port 1080.
diff --git a/docs/cmdline-opts/socks4a.d b/docs/cmdline-opts/socks4a.d
index ae254ae0e..d3177a9d7 100644
--- a/docs/cmdline-opts/socks4a.d
+++ b/docs/cmdline-opts/socks4a.d
@@ -2,6 +2,7 @@ Long: socks4a
Arg: <host[:port]>
Help: SOCKS4a proxy on given host + port
Added: 7.18.0
+Category: proxy
---
Use the specified SOCKS4a proxy. If the port number is not specified, it is
assumed at port 1080.
diff --git a/docs/cmdline-opts/socks5-basic.d b/docs/cmdline-opts/socks5-basic.d
index 67d16b3a6..52d1e6619 100644
--- a/docs/cmdline-opts/socks5-basic.d
+++ b/docs/cmdline-opts/socks5-basic.d
@@ -1,6 +1,7 @@
Long: socks5-basic
Help: Enable username/password auth for SOCKS5 proxies
Added: 7.55.0
+Category: proxy auth
---
Tells curl to use username/password authentication when connecting to a SOCKS5
proxy. The username/password authentication is enabled by default. Use
diff --git a/docs/cmdline-opts/socks5-gssapi-nec.d b/docs/cmdline-opts/socks5-gssapi-nec.d
index 477e218e3..b538f33f3 100644
--- a/docs/cmdline-opts/socks5-gssapi-nec.d
+++ b/docs/cmdline-opts/socks5-gssapi-nec.d
@@ -1,6 +1,7 @@
Long: socks5-gssapi-nec
Help: Compatibility with NEC SOCKS5 server
Added: 7.19.4
+Category: proxy auth
---
As part of the GSS-API negotiation a protection mode is negotiated. RFC 1961
says in section 4.3/4.4 it should be protected, but the NEC reference
diff --git a/docs/cmdline-opts/socks5-gssapi-service.d b/docs/cmdline-opts/socks5-gssapi-service.d
index eb3b2407b..e61d0f5ab 100644
--- a/docs/cmdline-opts/socks5-gssapi-service.d
+++ b/docs/cmdline-opts/socks5-gssapi-service.d
@@ -2,6 +2,7 @@ Long: socks5-gssapi-service
Arg: <name>
Help: SOCKS5 proxy service name for GSS-API
Added: 7.19.4
+Category: proxy auth
---
The default service name for a socks server is rcmd/server-fqdn. This option
allows you to change it.
diff --git a/docs/cmdline-opts/socks5-gssapi.d b/docs/cmdline-opts/socks5-gssapi.d
index 0070f37eb..72ae7aeb2 100644
--- a/docs/cmdline-opts/socks5-gssapi.d
+++ b/docs/cmdline-opts/socks5-gssapi.d
@@ -1,6 +1,7 @@
Long: socks5-gssapi
Help: Enable GSS-API auth for SOCKS5 proxies
Added: 7.55.0
+Category: proxy auth
---
Tells curl to use GSS-API authentication when connecting to a SOCKS5 proxy.
The GSS-API authentication is enabled by default (if curl is compiled with
diff --git a/docs/cmdline-opts/socks5-hostname.d b/docs/cmdline-opts/socks5-hostname.d
index 9d9d946e5..247d7660e 100644
--- a/docs/cmdline-opts/socks5-hostname.d
+++ b/docs/cmdline-opts/socks5-hostname.d
@@ -2,6 +2,7 @@ Long: socks5-hostname
Arg: <host[:port]>
Help: SOCKS5 proxy, pass host name to proxy
Added: 7.18.0
+Category: proxy
---
Use the specified SOCKS5 proxy (and let the proxy resolve the host name). If
the port number is not specified, it is assumed at port 1080.
diff --git a/docs/cmdline-opts/socks5.d b/docs/cmdline-opts/socks5.d
index 22fae7629..bbe92f0a1 100644
--- a/docs/cmdline-opts/socks5.d
+++ b/docs/cmdline-opts/socks5.d
@@ -2,6 +2,7 @@ Long: socks5
Arg: <host[:port]>
Help: SOCKS5 proxy on given host + port
Added: 7.18.0
+Category: proxy
---
Use the specified SOCKS5 proxy - but resolve the host name locally. If the
port number is not specified, it is assumed at port 1080.
diff --git a/docs/cmdline-opts/speed-limit.d b/docs/cmdline-opts/speed-limit.d
index e2b81c79a..3f9ad3a46 100644
--- a/docs/cmdline-opts/speed-limit.d
+++ b/docs/cmdline-opts/speed-limit.d
@@ -2,6 +2,7 @@ Long: speed-limit
Short: Y
Arg: <speed>
Help: Stop transfers slower than this
+Category: connection
---
If a download is slower than this given speed (in bytes per second) for
speed-time seconds it gets aborted. speed-time is set with --speed-time and is
diff --git a/docs/cmdline-opts/speed-time.d b/docs/cmdline-opts/speed-time.d
index 98d6ae13c..81acabec4 100644
--- a/docs/cmdline-opts/speed-time.d
+++ b/docs/cmdline-opts/speed-time.d
@@ -2,6 +2,7 @@ Long: speed-time
Short: y
Arg: <seconds>
Help: Trigger 'speed-limit' abort after this time
+Category: connection
---
If a download is slower than speed-limit bytes per second during a speed-time
period, the download gets aborted. If speed-time is used, the default
diff --git a/docs/cmdline-opts/ssl-allow-beast.d b/docs/cmdline-opts/ssl-allow-beast.d
index 973fcd451..f18fe7470 100644
--- a/docs/cmdline-opts/ssl-allow-beast.d
+++ b/docs/cmdline-opts/ssl-allow-beast.d
@@ -1,6 +1,7 @@
Long: ssl-allow-beast
Help: Allow security flaw to improve interop
Added: 7.25.0
+Category: tls
---
This option tells curl to not work around a security flaw in the SSL3 and
TLS1.0 protocols known as BEAST. If this option isn't used, the SSL layer may
diff --git a/docs/cmdline-opts/ssl-no-revoke.d b/docs/cmdline-opts/ssl-no-revoke.d
index f94b11143..3b1614243 100644
--- a/docs/cmdline-opts/ssl-no-revoke.d
+++ b/docs/cmdline-opts/ssl-no-revoke.d
@@ -1,6 +1,7 @@
Long: ssl-no-revoke
Help: Disable cert revocation checks (Schannel)
Added: 7.44.0
+Category: tls
---
(Schannel) This option tells curl to disable certificate revocation checks.
WARNING: this option loosens the SSL security, and by using this flag you ask
diff --git a/docs/cmdline-opts/ssl-reqd.d b/docs/cmdline-opts/ssl-reqd.d
index 3c6f8a257..2e573e39d 100644
--- a/docs/cmdline-opts/ssl-reqd.d
+++ b/docs/cmdline-opts/ssl-reqd.d
@@ -2,6 +2,7 @@ Long: ssl-reqd
Help: Require SSL/TLS
Protocols: FTP IMAP POP3 SMTP
Added: 7.20.0
+Category: tls
---
Require SSL/TLS for the connection. Terminates the connection if the server
doesn't support SSL/TLS.
diff --git a/docs/cmdline-opts/ssl-revoke-best-effort.d b/docs/cmdline-opts/ssl-revoke-best-effort.d
index e339b8af0..af22da461 100644
--- a/docs/cmdline-opts/ssl-revoke-best-effort.d
+++ b/docs/cmdline-opts/ssl-revoke-best-effort.d
@@ -1,6 +1,7 @@
Long: ssl-revoke-best-effort
Help: Ignore missing/offline cert CRL dist points
Added: 7.70.0
+Category: tls
---
(Schannel) This option tells curl to ignore certificate revocation checks when
they failed due to missing/offline distribution points for the revocation check
diff --git a/docs/cmdline-opts/ssl.d b/docs/cmdline-opts/ssl.d
index dabd83761..8df460106 100644
--- a/docs/cmdline-opts/ssl.d
+++ b/docs/cmdline-opts/ssl.d
@@ -2,6 +2,7 @@ Long: ssl
Help: Try SSL/TLS
Protocols: FTP IMAP POP3 SMTP
Added: 7.20.0
+Category: tls
---
Try to use SSL/TLS for the connection. Reverts to a non-secure connection if
diff --git a/docs/cmdline-opts/sslv2.d b/docs/cmdline-opts/sslv2.d
index 67d2b8506..773ab691e 100644
--- a/docs/cmdline-opts/sslv2.d
+++ b/docs/cmdline-opts/sslv2.d
@@ -7,6 +7,7 @@ Mutexed: sslv3 tlsv1 tlsv1.1 tlsv1.2
Requires: TLS
See-also: http1.1 http2
Help: Use SSLv2
+Category: tls
---
Forces curl to use SSL version 2 when negotiating with a remote SSL
server. Sometimes curl is built without SSLv2 support. SSLv2 is widely
diff --git a/docs/cmdline-opts/sslv3.d b/docs/cmdline-opts/sslv3.d
index 101ad1004..7beed8f81 100644
--- a/docs/cmdline-opts/sslv3.d
+++ b/docs/cmdline-opts/sslv3.d
@@ -7,6 +7,7 @@ Mutexed: sslv2 tlsv1 tlsv1.1 tlsv1.2
Requires: TLS
See-also: http1.1 http2
Help: Use SSLv3
+Category: tls
---
Forces curl to use SSL version 3 when negotiating with a remote SSL
server. Sometimes curl is built without SSLv3 support. SSLv3 is widely
diff --git a/docs/cmdline-opts/stderr.d b/docs/cmdline-opts/stderr.d
index e8cf7ba68..6da040159 100644
--- a/docs/cmdline-opts/stderr.d
+++ b/docs/cmdline-opts/stderr.d
@@ -1,6 +1,7 @@
Long: stderr
Help: Where to redirect stderr
See-also: verbose silent
+Category: verbose
---
Redirect all writes to stderr to the specified file instead. If the file name
is a plain '-', it is instead written to stdout.
diff --git a/docs/cmdline-opts/styled-output.d b/docs/cmdline-opts/styled-output.d
index e4751aecb..8aa4a0f05 100644
--- a/docs/cmdline-opts/styled-output.d
+++ b/docs/cmdline-opts/styled-output.d
@@ -1,6 +1,7 @@
Long: styled-output
Help: Enable styled output for HTTP headers
Added: 7.61.0
+Category: verbose
---
Enables the automatic use of bold font styles when writing HTTP headers to the
terminal. Use --no-styled-output to switch them off.
diff --git a/docs/cmdline-opts/suppress-connect-headers.d b/docs/cmdline-opts/suppress-connect-headers.d
index d208b8917..b4e2a17db 100644
--- a/docs/cmdline-opts/suppress-connect-headers.d
+++ b/docs/cmdline-opts/suppress-connect-headers.d
@@ -1,6 +1,7 @@
Long: suppress-connect-headers
Help: Suppress proxy CONNECT response headers
See-also: dump-header include proxytunnel
+Category: proxy
---
When --proxytunnel is used and a CONNECT request is made don't output proxy
CONNECT response headers. This option is meant to be used with --dump-header or
diff --git a/docs/cmdline-opts/tcp-fastopen.d b/docs/cmdline-opts/tcp-fastopen.d
index 08e141df7..faef499f3 100644
--- a/docs/cmdline-opts/tcp-fastopen.d
+++ b/docs/cmdline-opts/tcp-fastopen.d
@@ -1,5 +1,6 @@
Long: tcp-fastopen
Added: 7.49.0
Help: Use TCP Fast Open
+Category: connection
---
Enable use of TCP Fast Open (RFC7413).
diff --git a/docs/cmdline-opts/tcp-nodelay.d b/docs/cmdline-opts/tcp-nodelay.d
index f047a7c6f..f1cf644a4 100644
--- a/docs/cmdline-opts/tcp-nodelay.d
+++ b/docs/cmdline-opts/tcp-nodelay.d
@@ -1,6 +1,7 @@
Long: tcp-nodelay
Help: Use the TCP_NODELAY option
Added: 7.11.2
+Category: connection
---
Turn on the TCP_NODELAY option. See the \fIcurl_easy_setopt(3)\fP man page for
details about this option.
diff --git a/docs/cmdline-opts/telnet-option.d b/docs/cmdline-opts/telnet-option.d
index a67cb627b..789de3ea1 100644
--- a/docs/cmdline-opts/telnet-option.d
+++ b/docs/cmdline-opts/telnet-option.d
@@ -2,6 +2,7 @@ Long: telnet-option
Short: t
Arg: <opt=val>
Help: Set telnet option
+Category: telnet
---
Pass options to the telnet protocol. Supported options are:
diff --git a/docs/cmdline-opts/tftp-blksize.d b/docs/cmdline-opts/tftp-blksize.d
index c184328de..6e67ed2e1 100644
--- a/docs/cmdline-opts/tftp-blksize.d
+++ b/docs/cmdline-opts/tftp-blksize.d
@@ -3,6 +3,7 @@ Arg: <value>
Help: Set TFTP BLKSIZE option
Protocols: TFTP
Added: 7.20.0
+Category: tftp
---
Set TFTP BLKSIZE option (must be >512). This is the block size that curl will
try to use when transferring data to or from a TFTP server. By default 512
diff --git a/docs/cmdline-opts/tftp-no-options.d b/docs/cmdline-opts/tftp-no-options.d
index e2a4dacd5..023327301 100644
--- a/docs/cmdline-opts/tftp-no-options.d
+++ b/docs/cmdline-opts/tftp-no-options.d
@@ -2,6 +2,7 @@ Long: tftp-no-options
Help: Do not send any TFTP options
Protocols: TFTP
Added: 7.48.0
+Category: tftp
---
Tells curl not to send TFTP options requests.
diff --git a/docs/cmdline-opts/time-cond.d b/docs/cmdline-opts/time-cond.d
index 830b4e1a2..f733eeb0b 100644
--- a/docs/cmdline-opts/time-cond.d
+++ b/docs/cmdline-opts/time-cond.d
@@ -3,6 +3,7 @@ Short: z
Arg: <time>
Help: Transfer based on a time condition
Protocols: HTTP FTP
+Category: http ftp
---
Request a file that has been modified later than the given time and date, or
one that has been modified before that time. The <date expression> can be all
diff --git a/docs/cmdline-opts/tls-max.d b/docs/cmdline-opts/tls-max.d
index 475c12fe8..07eb65465 100644
--- a/docs/cmdline-opts/tls-max.d
+++ b/docs/cmdline-opts/tls-max.d
@@ -6,6 +6,7 @@ Added: 7.54.0
Requires: TLS
See-also: tlsv1.0 tlsv1.1 tlsv1.2 tlsv1.3
Help: Set maximum allowed TLS version
+Category: tls
---
VERSION defines maximum supported TLS version. The minimum acceptable version
is set by tlsv1.0, tlsv1.1, tlsv1.2 or tlsv1.3.
diff --git a/docs/cmdline-opts/tls13-ciphers.d b/docs/cmdline-opts/tls13-ciphers.d
index db8033525..0df1695b4 100644
--- a/docs/cmdline-opts/tls13-ciphers.d
+++ b/docs/cmdline-opts/tls13-ciphers.d
@@ -2,12 +2,13 @@ Long: tls13-ciphers
Arg: <ciphersuite list>
help: TLS 1.3 cipher suites to use
Protocols: TLS
+Category: tls
---
Specifies which cipher suites to use in the connection if it negotiates TLS
1.3. The list of ciphers suites must specify valid ciphers. Read up on TLS 1.3
cipher suite details on this URL:
- https://curl.haxx.se/docs/ssl-ciphers.html
+ https://curl.se/docs/ssl-ciphers.html
This option is currently used only when curl is built to use OpenSSL 1.1.1 or
later. If you are using a different SSL backend you can try setting TLS 1.3
diff --git a/docs/cmdline-opts/tlsauthtype.d b/docs/cmdline-opts/tlsauthtype.d
index ede21c2f7..5b283cf9b 100644
--- a/docs/cmdline-opts/tlsauthtype.d
+++ b/docs/cmdline-opts/tlsauthtype.d
@@ -2,6 +2,7 @@ Long: tlsauthtype
Arg: <type>
Help: TLS authentication type
Added: 7.21.4
+Category: tls auth
---
Set TLS authentication type. Currently, the only supported option is "SRP",
for TLS-SRP (RFC 5054). If --tlsuser and --tlspassword are specified but
diff --git a/docs/cmdline-opts/tlspassword.d b/docs/cmdline-opts/tlspassword.d
index b2e65362e..5c6a0fa51 100644
--- a/docs/cmdline-opts/tlspassword.d
+++ b/docs/cmdline-opts/tlspassword.d
@@ -1,6 +1,7 @@
Long: tlspassword
Help: TLS password
Added: 7.21.4
+Category: tls auth
---
Set password for use with the TLS authentication method specified with
--tlsauthtype. Requires that --tlsuser also be set.
diff --git a/docs/cmdline-opts/tlsuser.d b/docs/cmdline-opts/tlsuser.d
index 7192b9f1d..ada152608 100644
--- a/docs/cmdline-opts/tlsuser.d
+++ b/docs/cmdline-opts/tlsuser.d
@@ -2,6 +2,7 @@ Long: tlsuser
Arg: <name>
Help: TLS user name
Added: 7.21.4
+Category: tls auth
---
Set username for use with the TLS authentication method specified with
--tlsauthtype. Requires that --tlspassword also is set.
diff --git a/docs/cmdline-opts/tlsv1.0.d b/docs/cmdline-opts/tlsv1.0.d
index 2b1f0156a..4f0176f31 100644
--- a/docs/cmdline-opts/tlsv1.0.d
+++ b/docs/cmdline-opts/tlsv1.0.d
@@ -2,6 +2,7 @@ Long: tlsv1.0
Help: Use TLSv1.0 or greater
Protocols: TLS
Added: 7.34.0
+Category: tls
---
Forces curl to use TLS version 1.0 or later when connecting to a remote TLS server.
diff --git a/docs/cmdline-opts/tlsv1.1.d b/docs/cmdline-opts/tlsv1.1.d
index 405d552bb..b3649f7f4 100644
--- a/docs/cmdline-opts/tlsv1.1.d
+++ b/docs/cmdline-opts/tlsv1.1.d
@@ -2,6 +2,7 @@ Long: tlsv1.1
Help: Use TLSv1.1 or greater
Protocols: TLS
Added: 7.34.0
+Category: tls
---
Forces curl to use TLS version 1.1 or later when connecting to a remote TLS server.
diff --git a/docs/cmdline-opts/tlsv1.2.d b/docs/cmdline-opts/tlsv1.2.d
index bdf1fcf62..dffbccb9d 100644
--- a/docs/cmdline-opts/tlsv1.2.d
+++ b/docs/cmdline-opts/tlsv1.2.d
@@ -2,6 +2,7 @@ Long: tlsv1.2
Help: Use TLSv1.2 or greater
Protocols: TLS
Added: 7.34.0
+Category: tls
---
Forces curl to use TLS version 1.2 or later when connecting to a remote TLS server.
diff --git a/docs/cmdline-opts/tlsv1.3.d b/docs/cmdline-opts/tlsv1.3.d
index 19da857b7..37d953552 100644
--- a/docs/cmdline-opts/tlsv1.3.d
+++ b/docs/cmdline-opts/tlsv1.3.d
@@ -2,6 +2,7 @@ Long: tlsv1.3
Help: Use TLSv1.3 or greater
Protocols: TLS
Added: 7.52.0
+Category: tls
---
Forces curl to use TLS version 1.3 or later when connecting to a remote TLS
server.
diff --git a/docs/cmdline-opts/tlsv1.d b/docs/cmdline-opts/tlsv1.d
index 4cb405697..d4c0c5160 100644
--- a/docs/cmdline-opts/tlsv1.d
+++ b/docs/cmdline-opts/tlsv1.d
@@ -7,6 +7,7 @@ Mutexed: tlsv1.1 tlsv1.2 tlsv1.3
Requires: TLS
See-also: http1.1 http2
Help: Use TLSv1.0 or greater
+Category: tls
---
Tells curl to use at least TLS version 1.x when negotiating with a remote TLS
server. That means TLS version 1.0 or higher
diff --git a/docs/cmdline-opts/tr-encoding.d b/docs/cmdline-opts/tr-encoding.d
index 01bb62bb3..ce1d00325 100644
--- a/docs/cmdline-opts/tr-encoding.d
+++ b/docs/cmdline-opts/tr-encoding.d
@@ -2,6 +2,7 @@ Long: tr-encoding
Added: 7.21.6
Help: Request compressed transfer encoding
Protocols: HTTP
+Category: http
---
Request a compressed Transfer-Encoding response using one of the algorithms
curl supports, and uncompress the data while receiving it.
diff --git a/docs/cmdline-opts/trace-ascii.d b/docs/cmdline-opts/trace-ascii.d
index fceaa7126..fa7e16ccc 100644
--- a/docs/cmdline-opts/trace-ascii.d
+++ b/docs/cmdline-opts/trace-ascii.d
@@ -2,6 +2,7 @@ Long: trace-ascii
Arg: <file>
Help: Like --trace, but without hex output
Mutexed: trace verbose
+Category: verbose
---
Enables a full trace dump of all incoming and outgoing data, including
descriptive information, to the given output file. Use "-" as filename to have
diff --git a/docs/cmdline-opts/trace-time.d b/docs/cmdline-opts/trace-time.d
index 27dcc42cf..19a31a70e 100644
--- a/docs/cmdline-opts/trace-time.d
+++ b/docs/cmdline-opts/trace-time.d
@@ -1,5 +1,6 @@
Long: trace-time
Help: Add time stamps to trace/verbose output
Added: 7.14.0
+Category: verbose
---
Prepends a time stamp to each trace or verbose line that curl displays.
diff --git a/docs/cmdline-opts/trace.d b/docs/cmdline-opts/trace.d
index 334ea5ad6..502dafd71 100644
--- a/docs/cmdline-opts/trace.d
+++ b/docs/cmdline-opts/trace.d
@@ -2,6 +2,7 @@ Long: trace
Arg: <file>
Help: Write a debug trace to FILE
Mutexed: verbose trace-ascii
+Category: verbose
---
Enables a full trace dump of all incoming and outgoing data, including
descriptive information, to the given output file. Use "-" as filename to have
diff --git a/docs/cmdline-opts/unix-socket.d b/docs/cmdline-opts/unix-socket.d
index 812d20f3b..e4ea91d01 100644
--- a/docs/cmdline-opts/unix-socket.d
+++ b/docs/cmdline-opts/unix-socket.d
@@ -3,5 +3,6 @@ Arg: <path>
Help: Connect through this Unix domain socket
Added: 7.40.0
Protocols: HTTP
+Category: connection
---
Connect through this Unix domain socket, instead of using the network.
diff --git a/docs/cmdline-opts/upload-file.d b/docs/cmdline-opts/upload-file.d
index 6f01dbf35..63584b797 100644
--- a/docs/cmdline-opts/upload-file.d
+++ b/docs/cmdline-opts/upload-file.d
@@ -2,6 +2,7 @@ Long: upload-file
Short: T
Arg: <file>
Help: Transfer local FILE to destination
+Category: important upload
---
This transfers the specified local file to the remote URL. If there is no file
part in the specified URL, curl will append the local file name. NOTE that you
diff --git a/docs/cmdline-opts/url.d b/docs/cmdline-opts/url.d
index 991f1f27c..30f0bf72e 100644
--- a/docs/cmdline-opts/url.d
+++ b/docs/cmdline-opts/url.d
@@ -1,6 +1,7 @@
Long: url
Arg: <url>
Help: URL to work with
+Category: curl
---
Specify a URL to fetch. This option is mostly handy when you want to specify
URL(s) in a config file.
diff --git a/docs/cmdline-opts/use-ascii.d b/docs/cmdline-opts/use-ascii.d
index d59fad922..3a5a6a4f8 100644
--- a/docs/cmdline-opts/use-ascii.d
+++ b/docs/cmdline-opts/use-ascii.d
@@ -2,6 +2,7 @@ Short: B
Long: use-ascii
Help: Use ASCII/text transfer
Protocols: FTP LDAP
+Category: misc
---
Enable ASCII transfer. For FTP, this can also be enforced by using a URL that
ends with ";type=A". This option causes data sent to stdout to be in text mode
diff --git a/docs/cmdline-opts/user-agent.d b/docs/cmdline-opts/user-agent.d
index c6dd2e584..ec2ca82bb 100644
--- a/docs/cmdline-opts/user-agent.d
+++ b/docs/cmdline-opts/user-agent.d
@@ -3,6 +3,7 @@ Long: user-agent
Arg: <name>
Help: Send User-Agent <name> to server
Protocols: HTTP
+Category: important http
---
Specify the User-Agent string to send to the HTTP server. To encode blanks in
diff --git a/docs/cmdline-opts/user.d b/docs/cmdline-opts/user.d
index 7001d28ab..b588700c0 100644
--- a/docs/cmdline-opts/user.d
+++ b/docs/cmdline-opts/user.d
@@ -2,6 +2,7 @@ Long: user
Short: u
Arg: <user:password>
Help: Server user and password
+Category: important auth
---
Specify the user name and password to use for server authentication. Overrides
--netrc and --netrc-optional.
diff --git a/docs/cmdline-opts/verbose.d b/docs/cmdline-opts/verbose.d
index 5d3352183..8db1ea222 100644
--- a/docs/cmdline-opts/verbose.d
+++ b/docs/cmdline-opts/verbose.d
@@ -3,6 +3,7 @@ Long: verbose
Mutexed: trace trace-ascii
Help: Make the operation more talkative
See-also: include
+Category: important verbose
---
Makes curl verbose during the operation. Useful for debugging and seeing
what's going on "under the hood". A line starting with '>' means "header data"
diff --git a/docs/cmdline-opts/version.d b/docs/cmdline-opts/version.d
index 16c1843f1..f6c091707 100644
--- a/docs/cmdline-opts/version.d
+++ b/docs/cmdline-opts/version.d
@@ -1,6 +1,7 @@
Long: version
Short: V
Help: Show version number and quit
+Category: important curl
---
Displays information about curl and the libcurl version it uses.
@@ -27,6 +28,8 @@ This curl uses a libcurl built with Debug. This enables more error-tracking
and memory debugging etc. For curl-developers only!
.IP "GSS-API"
GSS-API is supported.
+.IP "HSTS"
+HSTS support is present.
.IP "HTTP2"
HTTP/2 support has been built-in.
.IP "HTTP3"
diff --git a/docs/cmdline-opts/write-out.d b/docs/cmdline-opts/write-out.d
index 686bda6ea..28b9a13a9 100644
--- a/docs/cmdline-opts/write-out.d
+++ b/docs/cmdline-opts/write-out.d
@@ -2,6 +2,7 @@ Long: write-out
Short: w
Arg: <format>
Help: Use output FORMAT after completion
+Category: verbose
---
Make curl display information on stdout after a completed transfer. The format
is a string that may contain plain text mixed with any number of
@@ -66,6 +67,10 @@ The http method used in the most recent HTTP request (Added in 7.72.0)
.B num_connects
Number of new connects made in the recent transfer. (Added in 7.12.3)
.TP
+.B num_headers
+The number of response headers in the most recent request (restarted at each
+ redirect). Note that the status line IS NOT a header. (Added in 7.73.0)
+.TP
.B num_redirects
Number of redirects that were followed in the request. (Added in 7.12.3)
.TP
diff --git a/docs/cmdline-opts/xattr.d b/docs/cmdline-opts/xattr.d
index b7553daeb..4b64c6cbf 100644
--- a/docs/cmdline-opts/xattr.d
+++ b/docs/cmdline-opts/xattr.d
@@ -1,5 +1,6 @@
Long: xattr
Help: Store metadata in extended file attributes
+Category: misc
---
When saving output to a file, this option tells curl to store certain file
metadata in extended file attributes. Currently, the URL is stored in the
diff --git a/docs/examples/.gitignore b/docs/examples/.gitignore
index cf5571bbf..45661bb7e 100644
--- a/docs/examples/.gitignore
+++ b/docs/examples/.gitignore
@@ -5,6 +5,7 @@ imap-authzid
pop3-authzid
smtp-authzid
10-at-a-time
+altsvc
anyauthput
certinfo
chkspeed
@@ -29,11 +30,14 @@ http2-download
http2-pushinmemory
http2-serverpush
http2-upload
+http3
+http3-present
httpcustomheader
httpput
+httpput-postfields
https
-imap
imap-append
+imap-authzid
imap-copy
imap-create
imap-delete
@@ -51,10 +55,12 @@ multi-app
multi-debugcallback
multi-double
multi-formadd
+multi-poll
multi-post
multi-single
parseurl
persistent
+pop3-authzid
pop3-dele
pop3-list
pop3-multi
@@ -65,8 +71,6 @@ pop3-stat
pop3-tls
pop3-top
pop3-uidl
-pop3s
-pop3slist
post-callback
postinmemory
postit2
@@ -81,8 +85,8 @@ sftpuploadresume
shared-connection-cache
simple
simplepost
-simplesmtp
simplessl
+smtp-authzid
smtp-expn
smtp-mail
smtp-mime
diff --git a/docs/examples/10-at-a-time.c b/docs/examples/10-at-a-time.c
index 12e5261fa..3f9e76076 100644
--- a/docs/examples/10-at-a-time.c
+++ b/docs/examples/10-at-a-time.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/Makefile.am b/docs/examples/Makefile.am
index dd37a687a..0777b12f8 100644
--- a/docs/examples/Makefile.am
+++ b/docs/examples/Makefile.am
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -22,7 +22,7 @@
AUTOMAKE_OPTIONS = foreign nostdinc
-EXTRA_DIST = README Makefile.example Makefile.inc Makefile.m32 \
+EXTRA_DIST = README.md Makefile.example Makefile.inc Makefile.m32 \
Makefile.netware makefile.dj $(COMPLICATED_EXAMPLES)
# Specify our include paths here, and do it relative to $(top_srcdir) and
diff --git a/docs/examples/Makefile.example b/docs/examples/Makefile.example
index 72e762fbb..e598d35dc 100644
--- a/docs/examples/Makefile.example
+++ b/docs/examples/Makefile.example
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/Makefile.inc b/docs/examples/Makefile.inc
index 79c9e509a..8b7b11b2c 100644
--- a/docs/examples/Makefile.inc
+++ b/docs/examples/Makefile.inc
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -36,7 +36,7 @@ check_PROGRAMS = 10-at-a-time anyauthput cookie_interface debug fileupload \
ftpuploadresume sslbackend postit2-formadd multi-formadd \
shared-connection-cache sftpuploadresume http2-pushinmemory parseurl \
urlapi imap-authzid pop3-authzid smtp-authzid http3 altsvc \
- http3-present multi-poll
+ http3-present multi-poll httpput-postfields
# These examples require external dependencies that may not be commonly
# available on POSIX systems, so don't bother attempting to compile them here.
diff --git a/docs/examples/Makefile.m32 b/docs/examples/Makefile.m32
index e8c0d376f..12ba11186 100644
--- a/docs/examples/Makefile.m32
+++ b/docs/examples/Makefile.m32
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -89,6 +89,14 @@ endif
ifndef NGHTTP2_PATH
NGHTTP2_PATH = ../../../nghttp2-1.0.0
endif
+# Edit the path below to point to the base of your nghttp3 package.
+ifndef NGHTTP3_PATH
+NGHTTP3_PATH = ../../../nghttp3-1.0.0
+endif
+# Edit the path below to point to the base of your ngtcp2 package.
+ifndef NGTCP2_PATH
+NGTCP2_PATH = ../../../ngtcp2-1.0.0
+endif
PROOT = ../..
@@ -215,6 +223,12 @@ endif
ifeq ($(findstring -nghttp2,$(CFG)),-nghttp2)
NGHTTP2 = 1
endif
+ifeq ($(findstring -nghttp3,$(CFG)),-nghttp3)
+NGHTTP3 = 1
+endif
+ifeq ($(findstring -ngtcp2,$(CFG)),-ngtcp2)
+NGTCP2 = 1
+endif
INCLUDES = -I. -I$(PROOT) -I$(PROOT)/include -I$(PROOT)/lib
@@ -252,6 +266,15 @@ ifdef SSH2
endif
endif
ifdef SSL
+ ifdef NGHTTP3
+ CFLAGS += -DUSE_NGHTTP3
+ curl_LDADD += -L"$(NGHTTP3_PATH)/lib" -lnghttp3
+ ifdef NGTCP2
+ CFLAGS += -DUSE_NGTCP2
+ curl_LDADD += -L"$(NGTCP2_PATH)/lib" -lngtcp2 -lngtcp2_crypto_openssl
+ endif
+ endif
+
ifndef OPENSSL_INCLUDE
ifeq "$(wildcard $(OPENSSL_PATH)/outinc)" "$(OPENSSL_PATH)/outinc"
OPENSSL_INCLUDE = $(OPENSSL_PATH)/outinc
@@ -294,7 +317,12 @@ endif
ifdef ZSTD
INCLUDES += -I"$(ZSTD_PATH)/include"
CFLAGS += -DHAVE_ZSTD
- curl_LDADD += -L"$(ZSTD_PATH)/lib" -lzstd
+ curl_LDADD += -L"$(ZSTD_PATH)/lib"
+ ifdef ZSTD_LIBS
+ curl_LDADD += $(ZSTD_LIBS)
+ else
+ curl_LDADD += -lzstd
+ endif
endif
ifdef BROTLI
INCLUDES += -I"$(BROTLI_PATH)/include"
diff --git a/docs/examples/Makefile.netware b/docs/examples/Makefile.netware
index 260c55773..3198e2664 100644
--- a/docs/examples/Makefile.netware
+++ b/docs/examples/Makefile.netware
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/README b/docs/examples/README.md
index 6336c3733..c83846566 100644
--- a/docs/examples/README
+++ b/docs/examples/README.md
@@ -1,8 +1,4 @@
- _ _ ____ _
- ___| | | | _ \| |
- / __| | | | |_) | |
- | (__| |_| | _ <| |___
- \___|\___/|_| \_\_____|
+# libcurl examples
This directory is for libcurl programming examples. They are meant to show
some simple steps on how you can build your own application to take full
@@ -11,26 +7,26 @@ advantage of libcurl.
If you end up with other small but still useful example sources, please mail
them for submission in future packages and on the website.
-BUILDING
+## Building
The Makefile.example is an example makefile that could be used to build these
examples. Just edit the file according to your system and requirements first.
Most examples should build fine using a command line like this:
- $ `curl-config --cc --cflags --libs` -o example example.c
+ `curl-config --cc --cflags --libs` -o example example.c
Some compilers don't like having the arguments in this order but instead
want you do reorganize them like:
- $ `curl-config --cc` -o example example.c `curl-config --cflags --libs`
+ `curl-config --cc` -o example example.c `curl-config --cflags --libs`
-*PLEASE* do not use the curl.haxx.se site as a test target for your libcurl
-applications/experiments. Even if some of the examples use that site as a URL
-at some places, it doesn't mean that the URLs work or that we expect you to
-actually torture our website with your tests! Thanks.
+**Please** do not use the `curl.se` site as a test target for your
+libcurl applications/experiments. Even if some of the examples use that site
+as a URL at some places, it doesn't mean that the URLs work or that we expect
+you to actually torture our website with your tests! Thanks.
-EXAMPLES
+## Examples
Each example source code file is designed to be and work stand-alone and
rather self-explanatory. The examples may at times lack the level of error
diff --git a/docs/examples/adddocsref.pl b/docs/examples/adddocsref.pl
index 3b01e36a2..96a4c3a98 100755
--- a/docs/examples/adddocsref.pl
+++ b/docs/examples/adddocsref.pl
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -23,7 +23,7 @@
# pass files as argument(s)
-my $docroot="https://curl.haxx.se/libcurl/c";
+my $docroot="https://curl.se/libcurl/c";
for $f (@ARGV) {
open(NEW, ">$f.new");
diff --git a/docs/examples/altsvc.c b/docs/examples/altsvc.c
index 2cd4b18d7..69e77e3c3 100644
--- a/docs/examples/altsvc.c
+++ b/docs/examples/altsvc.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/anyauthput.c b/docs/examples/anyauthput.c
index fe742c96d..71c243791 100644
--- a/docs/examples/anyauthput.c
+++ b/docs/examples/anyauthput.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/cacertinmem.c b/docs/examples/cacertinmem.c
index fd132809b..09d757cca 100644
--- a/docs/examples/cacertinmem.c
+++ b/docs/examples/cacertinmem.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/certinfo.c b/docs/examples/certinfo.c
index ee56f0e47..590b27da0 100644
--- a/docs/examples/certinfo.c
+++ b/docs/examples/certinfo.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/chkspeed.c b/docs/examples/chkspeed.c
index 70964c70d..5ff8ee18c 100644
--- a/docs/examples/chkspeed.c
+++ b/docs/examples/chkspeed.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/cookie_interface.c b/docs/examples/cookie_interface.c
index f645f29e7..e1715be70 100644
--- a/docs/examples/cookie_interface.c
+++ b/docs/examples/cookie_interface.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/debug.c b/docs/examples/debug.c
index 1a1c0c8cd..831f4460e 100644
--- a/docs/examples/debug.c
+++ b/docs/examples/debug.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/ephiperfifo.c b/docs/examples/ephiperfifo.c
index c0c972a6b..47707a893 100644
--- a/docs/examples/ephiperfifo.c
+++ b/docs/examples/ephiperfifo.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/evhiperfifo.c b/docs/examples/evhiperfifo.c
index cfce7fc06..6e613f510 100644
--- a/docs/examples/evhiperfifo.c
+++ b/docs/examples/evhiperfifo.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/externalsocket.c b/docs/examples/externalsocket.c
index 4bc12a325..f3691f9de 100644
--- a/docs/examples/externalsocket.c
+++ b/docs/examples/externalsocket.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/fileupload.c b/docs/examples/fileupload.c
index 096acb0b1..c18eef937 100644
--- a/docs/examples/fileupload.c
+++ b/docs/examples/fileupload.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/ftp-wildcard.c b/docs/examples/ftp-wildcard.c
index e560731bf..4ce89f1ee 100644
--- a/docs/examples/ftp-wildcard.c
+++ b/docs/examples/ftp-wildcard.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/ftpget.c b/docs/examples/ftpget.c
index 68e655305..71f5119d7 100644
--- a/docs/examples/ftpget.c
+++ b/docs/examples/ftpget.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/ftpgetinfo.c b/docs/examples/ftpgetinfo.c
index c6f190cac..761a06926 100644
--- a/docs/examples/ftpgetinfo.c
+++ b/docs/examples/ftpgetinfo.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -64,7 +64,7 @@ int main(void)
res = curl_easy_perform(curl);
if(CURLE_OK == res) {
- /* https://curl.haxx.se/libcurl/c/curl_easy_getinfo.html */
+ /* https://curl.se/libcurl/c/curl_easy_getinfo.html */
res = curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime);
if((CURLE_OK == res) && (filetime >= 0)) {
time_t file_time = (time_t)filetime;
diff --git a/docs/examples/ftpgetresp.c b/docs/examples/ftpgetresp.c
index 19723bc7b..9d440f3bd 100644
--- a/docs/examples/ftpgetresp.c
+++ b/docs/examples/ftpgetresp.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/ftpsget.c b/docs/examples/ftpsget.c
index dedd347b1..d865747f9 100644
--- a/docs/examples/ftpsget.c
+++ b/docs/examples/ftpsget.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/ftpupload.c b/docs/examples/ftpupload.c
index ff4dbae32..c07c97e60 100644
--- a/docs/examples/ftpupload.c
+++ b/docs/examples/ftpupload.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/ftpuploadfrommem.c b/docs/examples/ftpuploadfrommem.c
index ed1ea80d5..50bbf222f 100644
--- a/docs/examples/ftpuploadfrommem.c
+++ b/docs/examples/ftpuploadfrommem.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/ftpuploadresume.c b/docs/examples/ftpuploadresume.c
index c966c76e9..9678f5506 100644
--- a/docs/examples/ftpuploadresume.c
+++ b/docs/examples/ftpuploadresume.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/getinfo.c b/docs/examples/getinfo.c
index 2438f2f97..7693fcd11 100644
--- a/docs/examples/getinfo.c
+++ b/docs/examples/getinfo.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/getinmemory.c b/docs/examples/getinmemory.c
index 18c39f7b5..e42f8392c 100644
--- a/docs/examples/getinmemory.c
+++ b/docs/examples/getinmemory.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/getredirect.c b/docs/examples/getredirect.c
index a7f656d20..75603db21 100644
--- a/docs/examples/getredirect.c
+++ b/docs/examples/getredirect.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/ghiper.c b/docs/examples/ghiper.c
index a157094c7..fbab212a9 100644
--- a/docs/examples/ghiper.c
+++ b/docs/examples/ghiper.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/hiperfifo.c b/docs/examples/hiperfifo.c
index a7f71125a..cd5a4ee09 100644
--- a/docs/examples/hiperfifo.c
+++ b/docs/examples/hiperfifo.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/href_extractor.c b/docs/examples/href_extractor.c
index 2ec062cfb..a684fd09c 100644
--- a/docs/examples/href_extractor.c
+++ b/docs/examples/href_extractor.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/htmltidy.c b/docs/examples/htmltidy.c
index 9d4ad1a5d..9ee02da9f 100644
--- a/docs/examples/htmltidy.c
+++ b/docs/examples/htmltidy.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/htmltitle.cpp b/docs/examples/htmltitle.cpp
index 8dff811e8..8fe02aecb 100644
--- a/docs/examples/htmltitle.cpp
+++ b/docs/examples/htmltitle.cpp
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/http-post.c b/docs/examples/http-post.c
index e09f6de3e..204c45f0e 100644
--- a/docs/examples/http-post.c
+++ b/docs/examples/http-post.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/http2-download.c b/docs/examples/http2-download.c
index 3504c5af2..807b69449 100644
--- a/docs/examples/http2-download.c
+++ b/docs/examples/http2-download.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/http2-pushinmemory.c b/docs/examples/http2-pushinmemory.c
index b0e099bd8..a7c5a2784 100644
--- a/docs/examples/http2-pushinmemory.c
+++ b/docs/examples/http2-pushinmemory.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/http2-serverpush.c b/docs/examples/http2-serverpush.c
index 26d5a6927..bf494d610 100644
--- a/docs/examples/http2-serverpush.c
+++ b/docs/examples/http2-serverpush.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/http2-upload.c b/docs/examples/http2-upload.c
index 6aa48ecbc..22ec2dec3 100644
--- a/docs/examples/http2-upload.c
+++ b/docs/examples/http2-upload.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/http3-present.c b/docs/examples/http3-present.c
index 229964941..1128235b5 100644
--- a/docs/examples/http3-present.c
+++ b/docs/examples/http3-present.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/http3.c b/docs/examples/http3.c
index 1a283057d..27ace81d9 100644
--- a/docs/examples/http3.c
+++ b/docs/examples/http3.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/httpcustomheader.c b/docs/examples/httpcustomheader.c
index d98aa7a5a..dede209f7 100644
--- a/docs/examples/httpcustomheader.c
+++ b/docs/examples/httpcustomheader.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/httpput-postfields.c b/docs/examples/httpput-postfields.c
new file mode 100644
index 000000000..83c2d1f00
--- /dev/null
+++ b/docs/examples/httpput-postfields.c
@@ -0,0 +1,101 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* <DESC>
+ * HTTP PUT using CURLOPT_POSTFIELDS
+ * </DESC>
+ */
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <curl/curl.h>
+
+static const char olivertwist[]=
+ "Among other public buildings in a certain town, which for many reasons "
+ "it will be prudent to refrain from mentioning, and to which I will assign "
+ "no fictitious name, there is one anciently common to most towns, great or "
+ "small: to wit, a workhouse; and in this workhouse was born; on a day and "
+ "date which I need not trouble myself to repeat, inasmuch as it can be of "
+ "no possible consequence to the reader, in this stage of the business at "
+ "all events; the item of mortality whose name is prefixed to the head of "
+ "this chapter.";
+
+/*
+ * This example shows a HTTP PUT operation that sends a fixed buffer with
+ * CURLOPT_POSTFIELDS to the URL given as an argument.
+ */
+
+int main(int argc, char **argv)
+{
+ CURL *curl;
+ CURLcode res;
+ char *url;
+
+ if(argc < 2)
+ return 1;
+
+ url = argv[1];
+
+ /* In windows, this will init the winsock stuff */
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ /* get a curl handle */
+ curl = curl_easy_init();
+ if(curl) {
+ struct curl_slist *headers = NULL;
+
+ /* default type with postfields is application/x-www-form-urlencoded,
+ change it if you want */
+ headers = curl_slist_append(headers, "Content-Type: literature/classic");
+ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
+
+ /* pass on content in request body. When CURLOPT_POSTFIELDSIZE isn't used,
+ curl does strlen to get the size. */
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, olivertwist);
+
+ /* override the POST implied by CURLOPT_POSTFIELDS
+ *
+ * Warning: CURLOPT_CUSTOMREQUEST is problematic, especially if you want
+ * to follow redirects. Be aware.
+ */
+ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
+
+ /* specify target URL, and note that this URL should include a file
+ name, not only a directory */
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+
+ /* Now run off and do what you've been told! */
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+
+ /* free headers */
+ curl_slist_free_all(headers);
+ }
+
+ curl_global_cleanup();
+ return 0;
+}
diff --git a/docs/examples/httpput.c b/docs/examples/httpput.c
index 8399dbfe7..e7ace2bff 100644
--- a/docs/examples/httpput.c
+++ b/docs/examples/httpput.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -89,12 +89,9 @@ int main(int argc, char **argv)
/* we want to use our own read function */
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
- /* enable uploading */
+ /* enable uploading (implies PUT over HTTP) */
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
- /* HTTP PUT please */
- curl_easy_setopt(curl, CURLOPT_PUT, 1L);
-
/* specify target URL, and note that this URL should include a file
name, not only a directory */
curl_easy_setopt(curl, CURLOPT_URL, url);
diff --git a/docs/examples/https.c b/docs/examples/https.c
index 7e6116499..282f068c7 100644
--- a/docs/examples/https.c
+++ b/docs/examples/https.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/imap-append.c b/docs/examples/imap-append.c
index 56704d4c6..fc7dfb15f 100644
--- a/docs/examples/imap-append.c
+++ b/docs/examples/imap-append.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/imap-authzid.c b/docs/examples/imap-authzid.c
index 535084e2e..0074eb972 100644
--- a/docs/examples/imap-authzid.c
+++ b/docs/examples/imap-authzid.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/imap-copy.c b/docs/examples/imap-copy.c
index b24ffe026..699e825f6 100644
--- a/docs/examples/imap-copy.c
+++ b/docs/examples/imap-copy.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/imap-create.c b/docs/examples/imap-create.c
index caac825fa..72e426879 100644
--- a/docs/examples/imap-create.c
+++ b/docs/examples/imap-create.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/imap-delete.c b/docs/examples/imap-delete.c
index a8066032c..0edddd205 100644
--- a/docs/examples/imap-delete.c
+++ b/docs/examples/imap-delete.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/imap-examine.c b/docs/examples/imap-examine.c
index 700943365..3bb2a72cc 100644
--- a/docs/examples/imap-examine.c
+++ b/docs/examples/imap-examine.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/imap-fetch.c b/docs/examples/imap-fetch.c
index 30dfd39e4..a2e109dd9 100644
--- a/docs/examples/imap-fetch.c
+++ b/docs/examples/imap-fetch.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/imap-list.c b/docs/examples/imap-list.c
index 236d3101f..282542621 100644
--- a/docs/examples/imap-list.c
+++ b/docs/examples/imap-list.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/imap-lsub.c b/docs/examples/imap-lsub.c
index ed150a0b6..42415904f 100644
--- a/docs/examples/imap-lsub.c
+++ b/docs/examples/imap-lsub.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/imap-multi.c b/docs/examples/imap-multi.c
index c1f429e14..c67506059 100644
--- a/docs/examples/imap-multi.c
+++ b/docs/examples/imap-multi.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/imap-noop.c b/docs/examples/imap-noop.c
index 36aec963e..839da7be3 100644
--- a/docs/examples/imap-noop.c
+++ b/docs/examples/imap-noop.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/imap-search.c b/docs/examples/imap-search.c
index 07f95d9a3..41c19a348 100644
--- a/docs/examples/imap-search.c
+++ b/docs/examples/imap-search.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/imap-ssl.c b/docs/examples/imap-ssl.c
index 9e1ff3405..5f9152a2a 100644
--- a/docs/examples/imap-ssl.c
+++ b/docs/examples/imap-ssl.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/imap-store.c b/docs/examples/imap-store.c
index eba5f72d4..3fc3a4849 100644
--- a/docs/examples/imap-store.c
+++ b/docs/examples/imap-store.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/imap-tls.c b/docs/examples/imap-tls.c
index 0df1e63f4..2649056e8 100644
--- a/docs/examples/imap-tls.c
+++ b/docs/examples/imap-tls.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/makefile.dj b/docs/examples/makefile.dj
index eca16b8a6..3a1f05c01 100644
--- a/docs/examples/makefile.dj
+++ b/docs/examples/makefile.dj
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/multi-app.c b/docs/examples/multi-app.c
index 6359ee7c7..721853d6e 100644
--- a/docs/examples/multi-app.c
+++ b/docs/examples/multi-app.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/multi-debugcallback.c b/docs/examples/multi-debugcallback.c
index 32ea91491..6f92bbe97 100644
--- a/docs/examples/multi-debugcallback.c
+++ b/docs/examples/multi-debugcallback.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/multi-double.c b/docs/examples/multi-double.c
index b389b2e70..e245f583a 100644
--- a/docs/examples/multi-double.c
+++ b/docs/examples/multi-double.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/multi-event.c b/docs/examples/multi-event.c
index 307b316af..13a42955d 100644
--- a/docs/examples/multi-event.c
+++ b/docs/examples/multi-event.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/multi-formadd.c b/docs/examples/multi-formadd.c
index 96e4495f3..aa3faa089 100644
--- a/docs/examples/multi-formadd.c
+++ b/docs/examples/multi-formadd.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/multi-poll.c b/docs/examples/multi-poll.c
index 34e2ebc4b..7f66baae8 100644
--- a/docs/examples/multi-poll.c
+++ b/docs/examples/multi-poll.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/multi-post.c b/docs/examples/multi-post.c
index 2e12315cd..60afe5f7b 100644
--- a/docs/examples/multi-post.c
+++ b/docs/examples/multi-post.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/multi-single.c b/docs/examples/multi-single.c
index 6d63c2d23..3d038ee8c 100644
--- a/docs/examples/multi-single.c
+++ b/docs/examples/multi-single.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/multi-uv.c b/docs/examples/multi-uv.c
index e9cc7b125..0562fbea7 100644
--- a/docs/examples/multi-uv.c
+++ b/docs/examples/multi-uv.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/multithread.c b/docs/examples/multithread.c
index f25407e69..14b1f191c 100644
--- a/docs/examples/multithread.c
+++ b/docs/examples/multithread.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -36,11 +36,11 @@
If you intend to use a SSL-based protocol here you might need to setup TLS
library mutex callbacks as described here:
- https://curl.haxx.se/libcurl/c/threadsafe.html
+ https://curl.se/libcurl/c/threadsafe.html
*/
const char * const urls[NUMT]= {
- "https://curl.haxx.se/",
+ "https://curl.se/",
"ftp://cool.haxx.se/",
"https://www.cag.se/",
"www.haxx.se"
diff --git a/docs/examples/opensslthreadlock.c b/docs/examples/opensslthreadlock.c
index 649ef93a9..dac987ec6 100644
--- a/docs/examples/opensslthreadlock.c
+++ b/docs/examples/opensslthreadlock.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/parseurl.c b/docs/examples/parseurl.c
index d14174678..6dcecf99f 100644
--- a/docs/examples/parseurl.c
+++ b/docs/examples/parseurl.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/persistent.c b/docs/examples/persistent.c
index c5b289a44..b17448301 100644
--- a/docs/examples/persistent.c
+++ b/docs/examples/persistent.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/pop3-authzid.c b/docs/examples/pop3-authzid.c
index 8a50806dc..4226084d5 100644
--- a/docs/examples/pop3-authzid.c
+++ b/docs/examples/pop3-authzid.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/pop3-dele.c b/docs/examples/pop3-dele.c
index 45dbaa0f8..62238cd4d 100644
--- a/docs/examples/pop3-dele.c
+++ b/docs/examples/pop3-dele.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/pop3-list.c b/docs/examples/pop3-list.c
index 39b38a4d1..2c52c6c73 100644
--- a/docs/examples/pop3-list.c
+++ b/docs/examples/pop3-list.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/pop3-multi.c b/docs/examples/pop3-multi.c
index e86084394..a723ae03a 100644
--- a/docs/examples/pop3-multi.c
+++ b/docs/examples/pop3-multi.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/pop3-noop.c b/docs/examples/pop3-noop.c
index f0675e068..05a310174 100644
--- a/docs/examples/pop3-noop.c
+++ b/docs/examples/pop3-noop.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/pop3-retr.c b/docs/examples/pop3-retr.c
index 308a82fcb..727998473 100644
--- a/docs/examples/pop3-retr.c
+++ b/docs/examples/pop3-retr.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/pop3-ssl.c b/docs/examples/pop3-ssl.c
index 67aa647d3..1ef94d08f 100644
--- a/docs/examples/pop3-ssl.c
+++ b/docs/examples/pop3-ssl.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/pop3-stat.c b/docs/examples/pop3-stat.c
index 62832e83e..a7a1b46f0 100644
--- a/docs/examples/pop3-stat.c
+++ b/docs/examples/pop3-stat.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/pop3-tls.c b/docs/examples/pop3-tls.c
index 381f94268..8d3172878 100644
--- a/docs/examples/pop3-tls.c
+++ b/docs/examples/pop3-tls.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/pop3-top.c b/docs/examples/pop3-top.c
index c9ffd1f22..69b83321d 100644
--- a/docs/examples/pop3-top.c
+++ b/docs/examples/pop3-top.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/pop3-uidl.c b/docs/examples/pop3-uidl.c
index 9f6828c60..9ced73903 100644
--- a/docs/examples/pop3-uidl.c
+++ b/docs/examples/pop3-uidl.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/post-callback.c b/docs/examples/post-callback.c
index 324767bc1..3ffad9f85 100644
--- a/docs/examples/post-callback.c
+++ b/docs/examples/post-callback.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/postinmemory.c b/docs/examples/postinmemory.c
index 0cc66506e..6d008f4fb 100644
--- a/docs/examples/postinmemory.c
+++ b/docs/examples/postinmemory.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/postit2-formadd.c b/docs/examples/postit2-formadd.c
index af6348b25..b02eb3c8d 100644
--- a/docs/examples/postit2-formadd.c
+++ b/docs/examples/postit2-formadd.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/postit2.c b/docs/examples/postit2.c
index de352d3df..13062cd7c 100644
--- a/docs/examples/postit2.c
+++ b/docs/examples/postit2.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/progressfunc.c b/docs/examples/progressfunc.c
index fd366cf2f..03ee67f36 100644
--- a/docs/examples/progressfunc.c
+++ b/docs/examples/progressfunc.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/resolve.c b/docs/examples/resolve.c
index 75ee4e983..8e879710a 100644
--- a/docs/examples/resolve.c
+++ b/docs/examples/resolve.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/sampleconv.c b/docs/examples/sampleconv.c
index 97914ed8c..305952d32 100644
--- a/docs/examples/sampleconv.c
+++ b/docs/examples/sampleconv.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/sendrecv.c b/docs/examples/sendrecv.c
index b9c6bbc8f..ac49180f4 100644
--- a/docs/examples/sendrecv.c
+++ b/docs/examples/sendrecv.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/sepheaders.c b/docs/examples/sepheaders.c
index 548433135..5e400c749 100644
--- a/docs/examples/sepheaders.c
+++ b/docs/examples/sepheaders.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/sessioninfo.c b/docs/examples/sessioninfo.c
index 3941dc924..082cae98f 100644
--- a/docs/examples/sessioninfo.c
+++ b/docs/examples/sessioninfo.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/sftpget.c b/docs/examples/sftpget.c
index 14230e95c..338e9020c 100644
--- a/docs/examples/sftpget.c
+++ b/docs/examples/sftpget.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/sftpuploadresume.c b/docs/examples/sftpuploadresume.c
index f428ae489..f503a560f 100644
--- a/docs/examples/sftpuploadresume.c
+++ b/docs/examples/sftpuploadresume.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/shared-connection-cache.c b/docs/examples/shared-connection-cache.c
index f1073b1fb..78429c06e 100644
--- a/docs/examples/shared-connection-cache.c
+++ b/docs/examples/shared-connection-cache.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -63,7 +63,7 @@ int main(void)
if(curl) {
CURLcode res;
- curl_easy_setopt(curl, CURLOPT_URL, "https://curl.haxx.se/");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://curl.se/");
/* use the share object */
curl_easy_setopt(curl, CURLOPT_SHARE, share);
diff --git a/docs/examples/simple.c b/docs/examples/simple.c
index 6296b0ef0..ecebd0d26 100644
--- a/docs/examples/simple.c
+++ b/docs/examples/simple.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/simplepost.c b/docs/examples/simplepost.c
index b4d3a0b9c..39b8b76b0 100644
--- a/docs/examples/simplepost.c
+++ b/docs/examples/simplepost.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/simplessl.c b/docs/examples/simplessl.c
index 7b6a2b71b..090d1eadb 100644
--- a/docs/examples/simplessl.c
+++ b/docs/examples/simplessl.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/smooth-gtk-thread.c b/docs/examples/smooth-gtk-thread.c
index af8c0ca6e..efe2e8b90 100644
--- a/docs/examples/smooth-gtk-thread.c
+++ b/docs/examples/smooth-gtk-thread.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/smtp-authzid.c b/docs/examples/smtp-authzid.c
index ad03638b9..f1c81ad1e 100644
--- a/docs/examples/smtp-authzid.c
+++ b/docs/examples/smtp-authzid.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/smtp-expn.c b/docs/examples/smtp-expn.c
index 2673ea2f6..4c3eb1966 100644
--- a/docs/examples/smtp-expn.c
+++ b/docs/examples/smtp-expn.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/smtp-mail.c b/docs/examples/smtp-mail.c
index 89a9fd5cd..85d47b63d 100644
--- a/docs/examples/smtp-mail.c
+++ b/docs/examples/smtp-mail.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/smtp-mime.c b/docs/examples/smtp-mime.c
index 91fa89927..4d55f882f 100644
--- a/docs/examples/smtp-mime.c
+++ b/docs/examples/smtp-mime.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/smtp-multi.c b/docs/examples/smtp-multi.c
index a58f3282f..9f0335072 100644
--- a/docs/examples/smtp-multi.c
+++ b/docs/examples/smtp-multi.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/smtp-ssl.c b/docs/examples/smtp-ssl.c
index fcb692326..0e88d2d88 100644
--- a/docs/examples/smtp-ssl.c
+++ b/docs/examples/smtp-ssl.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/smtp-tls.c b/docs/examples/smtp-tls.c
index 92ccec1ac..b5469c9c6 100644
--- a/docs/examples/smtp-tls.c
+++ b/docs/examples/smtp-tls.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/smtp-vrfy.c b/docs/examples/smtp-vrfy.c
index e8c494423..9b4c925ff 100644
--- a/docs/examples/smtp-vrfy.c
+++ b/docs/examples/smtp-vrfy.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/sslbackend.c b/docs/examples/sslbackend.c
index b19e3dccd..2b33863dd 100644
--- a/docs/examples/sslbackend.c
+++ b/docs/examples/sslbackend.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -47,7 +47,7 @@ int main(int argc, char **argv)
const curl_ssl_backend **list;
int i;
- result = curl_global_sslset(-1, NULL, &list);
+ result = curl_global_sslset((curl_sslbackend)-1, NULL, &list);
assert(result == CURLSSLSET_UNKNOWN_BACKEND);
for(i = 0; list[i]; i++)
@@ -62,7 +62,7 @@ int main(int argc, char **argv)
result = curl_global_sslset((curl_sslbackend)id, NULL, NULL);
}
else
- result = curl_global_sslset(-1, name, NULL);
+ result = curl_global_sslset((curl_sslbackend)-1, name, NULL);
if(result == CURLSSLSET_UNKNOWN_BACKEND) {
fprintf(stderr, "Unknown SSL backend id: %s\n", name);
diff --git a/docs/examples/synctime.c b/docs/examples/synctime.c
index 2806965b5..f5f8e1ad6 100644
--- a/docs/examples/synctime.c
+++ b/docs/examples/synctime.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/threaded-shared-conn.c b/docs/examples/threaded-shared-conn.c
index baa83b4e7..d13e0d3e3 100644
--- a/docs/examples/threaded-shared-conn.c
+++ b/docs/examples/threaded-shared-conn.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/threaded-ssl.c b/docs/examples/threaded-ssl.c
index cef0cf470..da4c1d7a0 100644
--- a/docs/examples/threaded-ssl.c
+++ b/docs/examples/threaded-ssl.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/url2file.c b/docs/examples/url2file.c
index f975db2a2..c46a59629 100644
--- a/docs/examples/url2file.c
+++ b/docs/examples/url2file.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/urlapi.c b/docs/examples/urlapi.c
index fcddfda57..7af2b3fdf 100644
--- a/docs/examples/urlapi.c
+++ b/docs/examples/urlapi.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/usercertinmem.c b/docs/examples/usercertinmem.c
index 92f9655e2..15b922171 100644
--- a/docs/examples/usercertinmem.c
+++ b/docs/examples/usercertinmem.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2013 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2013 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/version-check.pl b/docs/examples/version-check.pl
index c8bc3a849..46450f6dd 100755
--- a/docs/examples/version-check.pl
+++ b/docs/examples/version-check.pl
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/docs/examples/xmlstream.c b/docs/examples/xmlstream.c
index 8b5b29e79..70509ec97 100644
--- a/docs/examples/xmlstream.c
+++ b/docs/examples/xmlstream.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/docs/gnurl-config.1 b/docs/gnurl-config.1
index 84fd0576f..e7e1b6c19 100644
--- a/docs/gnurl-config.1
+++ b/docs/gnurl-config.1
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/CMakeLists.txt b/docs/libcurl/CMakeLists.txt
index 8ef604a42..948a72121 100644
--- a/docs/libcurl/CMakeLists.txt
+++ b/docs/libcurl/CMakeLists.txt
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/Makefile.am b/docs/libcurl/Makefile.am
index 224eff1c2..862600ac2 100644
--- a/docs/libcurl/Makefile.am
+++ b/docs/libcurl/Makefile.am
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/Makefile.inc b/docs/libcurl/Makefile.inc
index fe3dd65a8..30eb779e2 100644
--- a/docs/libcurl/Makefile.inc
+++ b/docs/libcurl/Makefile.inc
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -23,85 +23,88 @@
# Shared between Makefile.am and CMakeLists.txt
man_MANS = \
- gnurl_easy_cleanup.3 \
- gnurl_easy_duphandle.3 \
- gnurl_easy_escape.3 \
- gnurl_easy_getinfo.3 \
- gnurl_easy_init.3 \
- gnurl_easy_pause.3 \
- gnurl_easy_perform.3 \
- gnurl_easy_recv.3 \
- gnurl_easy_reset.3 \
- gnurl_easy_send.3 \
- gnurl_easy_setopt.3 \
- gnurl_easy_strerror.3 \
- gnurl_easy_unescape.3 \
- gnurl_easy_upkeep.3 \
- gnurl_escape.3 \
- gnurl_formadd.3 \
- gnurl_formfree.3 \
- gnurl_formget.3 \
- gnurl_free.3 \
- gnurl_getdate.3 \
- gnurl_getenv.3 \
- gnurl_global_cleanup.3 \
- gnurl_global_init.3 \
- gnurl_global_init_mem.3 \
- gnurl_global_sslset.3 \
- gnurl_mime_addpart.3 \
- gnurl_mime_data.3 \
- gnurl_mime_data_cb.3 \
- gnurl_mime_encoder.3 \
- gnurl_mime_filedata.3 \
- gnurl_mime_filename.3 \
- gnurl_mime_free.3 \
- gnurl_mime_headers.3 \
- gnurl_mime_init.3 \
- gnurl_mime_name.3 \
- gnurl_mime_subparts.3 \
- gnurl_mime_type.3 \
- gnurl_mprintf.3 \
- gnurl_multi_add_handle.3 \
- gnurl_multi_assign.3 \
- gnurl_multi_cleanup.3 \
- gnurl_multi_fdset.3 \
- gnurl_multi_info_read.3 \
- gnurl_multi_init.3 \
- gnurl_multi_perform.3 \
- gnurl_multi_poll.3 \
- gnurl_multi_remove_handle.3 \
- gnurl_multi_setopt.3 \
- gnurl_multi_socket.3 \
- gnurl_multi_socket_action.3 \
- gnurl_multi_socket_all.3 \
- gnurl_multi_strerror.3 \
- gnurl_multi_timeout.3 \
- gnurl_multi_wakeup.3 \
- gnurl_multi_wait.3 \
- gnurl_share_cleanup.3 \
- gnurl_share_init.3 \
- gnurl_share_setopt.3 \
- gnurl_share_strerror.3 \
- gnurl_slist_append.3 \
- gnurl_slist_free_all.3 \
- gnurl_strequal.3 \
- gnurl_strnequal.3 \
- gnurl_unescape.3 \
- gnurl_url.3 \
- gnurl_url_cleanup.3 \
- gnurl_url_dup.3 \
- gnurl_url_get.3 \
- gnurl_url_set.3 \
- gnurl_version.3 \
- gnurl_version_info.3 \
- libgnurl-easy.3 \
- libgnurl-env.3 \
- libgnurl-errors.3 \
- libgnurl-multi.3 \
- libgnurl-security.3 \
- libgnurl-share.3 \
- libgnurl-symbols.3 \
- libgnurl-thread.3 \
- libgnurl-tutorial.3 \
- libgnurl-url.3 \
- libgnurl.3
+ curl_easy_cleanup.3 \
+ curl_easy_duphandle.3 \
+ curl_easy_escape.3 \
+ curl_easy_getinfo.3 \
+ curl_easy_init.3 \
+ curl_easy_option_by_id.3 \
+ curl_easy_option_by_name.3 \
+ curl_easy_option_next.3 \
+ curl_easy_pause.3 \
+ curl_easy_perform.3 \
+ curl_easy_recv.3 \
+ curl_easy_reset.3 \
+ curl_easy_send.3 \
+ curl_easy_setopt.3 \
+ curl_easy_strerror.3 \
+ curl_easy_unescape.3 \
+ curl_easy_upkeep.3 \
+ curl_escape.3 \
+ curl_formadd.3 \
+ curl_formfree.3 \
+ curl_formget.3 \
+ curl_free.3 \
+ curl_getdate.3 \
+ curl_getenv.3 \
+ curl_global_cleanup.3 \
+ curl_global_init.3 \
+ curl_global_init_mem.3 \
+ curl_global_sslset.3 \
+ curl_mime_addpart.3 \
+ curl_mime_data.3 \
+ curl_mime_data_cb.3 \
+ curl_mime_encoder.3 \
+ curl_mime_filedata.3 \
+ curl_mime_filename.3 \
+ curl_mime_free.3 \
+ curl_mime_headers.3 \
+ curl_mime_init.3 \
+ curl_mime_name.3 \
+ curl_mime_subparts.3 \
+ curl_mime_type.3 \
+ curl_mprintf.3 \
+ curl_multi_add_handle.3 \
+ curl_multi_assign.3 \
+ curl_multi_cleanup.3 \
+ curl_multi_fdset.3 \
+ curl_multi_info_read.3 \
+ curl_multi_init.3 \
+ curl_multi_perform.3 \
+ curl_multi_poll.3 \
+ curl_multi_remove_handle.3 \
+ curl_multi_setopt.3 \
+ curl_multi_socket.3 \
+ curl_multi_socket_action.3 \
+ curl_multi_socket_all.3 \
+ curl_multi_strerror.3 \
+ curl_multi_timeout.3 \
+ curl_multi_wakeup.3 \
+ curl_multi_wait.3 \
+ curl_share_cleanup.3 \
+ curl_share_init.3 \
+ curl_share_setopt.3 \
+ curl_share_strerror.3 \
+ curl_slist_append.3 \
+ curl_slist_free_all.3 \
+ curl_strequal.3 \
+ curl_strnequal.3 \
+ curl_unescape.3 \
+ curl_url.3 \
+ curl_url_cleanup.3 \
+ curl_url_dup.3 \
+ curl_url_get.3 \
+ curl_url_set.3 \
+ curl_version.3 \
+ curl_version_info.3 \
+ libcurl-easy.3 \
+ libcurl-env.3 \
+ libcurl-errors.3 \
+ libcurl-multi.3 \
+ libcurl-security.3 \
+ libcurl-share.3 \
+ libcurl-symbols.3 \
+ libcurl-thread.3 \
+ libcurl-tutorial.3 \
+ libcurl-url.3 \
+ libcurl.3
diff --git a/docs/libcurl/curl_easy_option_by_id.3 b/docs/libcurl/curl_easy_option_by_id.3
new file mode 100644
index 000000000..f87e742e1
--- /dev/null
+++ b/docs/libcurl/curl_easy_option_by_id.3
@@ -0,0 +1,46 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at https://curl.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_easy_option_by_id 3 "27 Aug 2020" "libcurl 7.73.0" "libcurl Manual"
+.SH NAME
+curl_easy_option_by_id - find an easy setopt option by id
+.SH SYNOPSIS
+.nf
+#include <curl/curl.h>
+
+const struct curl_easyoption *curl_easy_option_by_id(CURLoption id);
+.fi
+.SH DESCRIPTION
+Given a CURLoption \fBid\fP, this function returns a pointer to the
+curl_easyoption struct, holding information about the
+\fIcurl_easy_setopt(3)\fP option using that id. The option id is the CURLOPT_
+prefix ones provided in the standard curl/curl.h header file. This function
+will return the non-aliases version for the cases where there is an alias
+function as well.
+
+If libcurl has no option with the given id, this function returns NULL.
+.SH AVAILABILITY
+This function was added in libcurl 7.73.0
+.SH RETURN VALUE
+A pointer to the curl_easyoption struct for the option or NULL.
+.SH "SEE ALSO"
+.BR curl_easy_option_by_name "(3)," curl_easy_option_next "(3),"
+.BR curl_easy_setopt "(3),"
diff --git a/docs/libcurl/curl_easy_option_by_name.3 b/docs/libcurl/curl_easy_option_by_name.3
new file mode 100644
index 000000000..0a62592ad
--- /dev/null
+++ b/docs/libcurl/curl_easy_option_by_name.3
@@ -0,0 +1,44 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at https://curl.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_easy_option_by_name 3 "27 Aug 2020" "libcurl 7.73.0" "libcurl Manual"
+.SH NAME
+curl_easy_option_by_name - find an easy setopt option by name
+.SH SYNOPSIS
+.nf
+#include <curl/curl.h>
+
+const struct curl_easyoption *curl_easy_option_by_name(const char *name);
+.fi
+.SH DESCRIPTION
+Given a \fBname\fP, this function returns a pointer to the curl_easyoption
+struct, holding information about the \fIcurl_easy_setopt(3)\fP option using
+that name. The name should be specified without the "CURLOPT_" prefix and the
+name comparison is made case insensitive.
+
+If libcurl has no option with the given name, this function returns NULL.
+.SH AVAILABILITY
+This function was added in libcurl 7.73.0
+.SH RETURN VALUE
+A pointer to the curl_easyoption struct for the option or NULL.
+.SH "SEE ALSO"
+.BR curl_easy_option_next "(3)," curl_easy_option_by_id "(3),"
+.BR curl_easy_setopt "(3),"
diff --git a/docs/libcurl/curl_easy_option_next.3 b/docs/libcurl/curl_easy_option_next.3
new file mode 100644
index 000000000..27165f06c
--- /dev/null
+++ b/docs/libcurl/curl_easy_option_next.3
@@ -0,0 +1,74 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at https://curl.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_easy_option_next 3 "27 Aug 2020" "libcurl 7.73.0" "libcurl Manual"
+.SH NAME
+curl_easy_option_next - iterate over easy setopt options
+.SH SYNOPSIS
+.nf
+#include <curl/curl.h>
+
+typedef enum {
+ CURLOT_LONG, /* long (a range of values) */
+ CURLOT_VALUES, /* (a defined set or bitmask) */
+ CURLOT_OFF_T, /* curl_off_t (a range of values) */
+ CURLOT_OBJECT, /* pointer (void *) */
+ CURLOT_STRING, /* (char * to zero terminated buffer) */
+ CURLOT_SLIST, /* (struct curl_slist *) */
+ CURLOT_CBPTR, /* (void * passed as-is to a callback) */
+ CURLOT_BLOB, /* blob (struct curl_blob *) */
+ CURLOT_FUNCTION /* function pointer */
+} curl_easytype;
+
+/* The CURLOPTTYPE_* id ranges can still be used to figure out what type/size
+ to use for curl_easy_setopt() for the given id */
+struct curl_easyoption {
+ const char *name;
+ CURLoption id;
+ curl_easytype type;
+ unsigned int flags;
+};
+
+const struct curl_easyoption *
+curl_easy_option_next(const struct curl_easyoption *prev);
+.fi
+.SH DESCRIPTION
+This function returns a pointer to the first or the next curl_easyoption
+struct, providing an ability to iterate over all known options for
+\fIcurl_easy_setopt(3)\fP in this instance of libcurl.
+
+Pass a \fBNULL\fP argument as \fBprev\fP to get the first option returned, or
+pass in the current option to get the next one returned. If there is no more
+option to return, \fIcurl_easy_option_next(3)\fP returns NULL.
+
+The options returned by this functions are the ones known to this libcurl and
+information about what argument type they want.
+
+If the \fBCURLOT_FLAG_ALIAS\fP bit is set in the flags field, it means the
+name is provided for backwards compatibility as an alias.
+.SH AVAILABILITY
+This function was added in libcurl 7.73.0
+.SH RETURN VALUE
+A pointer to the curl_easyoption struct for the next option or NULL if no more
+options.
+.SH "SEE ALSO"
+.BR curl_easy_option_by_name "(3)," curl_easy_option_by_id "(3),"
+.BR curl_easy_setopt "(3),"
diff --git a/docs/libcurl/gnurl_easy_cleanup.3 b/docs/libcurl/gnurl_easy_cleanup.3
index fd05f44fb..0411b1809 100644
--- a/docs/libcurl/gnurl_easy_cleanup.3
+++ b/docs/libcurl/gnurl_easy_cleanup.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -60,7 +60,7 @@ None
CURL *curl = curl_easy_init();
if(curl) {
CURLcode res;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
diff --git a/docs/libcurl/gnurl_easy_duphandle.3 b/docs/libcurl/gnurl_easy_duphandle.3
index bf413235c..df5277d2e 100644
--- a/docs/libcurl/gnurl_easy_duphandle.3
+++ b/docs/libcurl/gnurl_easy_duphandle.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_easy_escape.3 b/docs/libcurl/gnurl_easy_escape.3
index 8430ea1c2..fed95a650 100644
--- a/docs/libcurl/gnurl_easy_escape.3
+++ b/docs/libcurl/gnurl_easy_escape.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -36,7 +36,8 @@ a-z, A-Z, 0-9, '-', '.', '_' or '~' are converted to their "URL escaped"
version (%NN where NN is a two-digit hexadecimal number).
If \fIlength\fP is set to 0 (zero), \fIcurl_easy_escape(3)\fP uses strlen() on
-the input \fIstring\fP to find out the size.
+the input \fIstring\fP to find out the size. This function does not accept
+input strings longer than \fBCURL_MAX_INPUT_LENGTH\fP (8 MB).
You must \fIcurl_free(3)\fP the returned string when you're done with it.
.SH ENCODING
diff --git a/docs/libcurl/gnurl_easy_getinfo.3 b/docs/libcurl/gnurl_easy_getinfo.3
index c6a338e1c..105699377 100644
--- a/docs/libcurl/gnurl_easy_getinfo.3
+++ b/docs/libcurl/gnurl_easy_getinfo.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -141,6 +141,9 @@ See \fICURLINFO_REQUEST_SIZE(3)\fP
.IP CURLINFO_SSL_VERIFYRESULT
Certificate verification result.
See \fICURLINFO_SSL_VERIFYRESULT(3)\fP
+.IP CURLINFO_PROXY_ERROR
+Detailed proxy error.
+See \fICURLINFO_PROXY_ERROR(3)\fP
.IP CURLINFO_PROXY_SSL_VERIFYRESULT
Proxy certificate verification result.
See \fICURLINFO_PROXY_SSL_VERIFYRESULT(3)\fP
diff --git a/docs/libcurl/gnurl_easy_init.3 b/docs/libcurl/gnurl_easy_init.3
index a17400dc5..af8950038 100644
--- a/docs/libcurl/gnurl_easy_init.3
+++ b/docs/libcurl/gnurl_easy_init.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -49,7 +49,7 @@ other curl functions.
CURL *curl = curl_easy_init();
if(curl) {
CURLcode res;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
diff --git a/docs/libcurl/gnurl_easy_pause.3 b/docs/libcurl/gnurl_easy_pause.3
index 6d223f2dd..3f27639d2 100644
--- a/docs/libcurl/gnurl_easy_pause.3
+++ b/docs/libcurl/gnurl_easy_pause.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_easy_perform.3 b/docs/libcurl/gnurl_easy_perform.3
index 36c6675f0..6e1ea6f37 100644
--- a/docs/libcurl/gnurl_easy_perform.3
+++ b/docs/libcurl/gnurl_easy_perform.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -63,7 +63,7 @@ the error buffer when non-zero is returned.
CURL *curl = curl_easy_init();
if(curl) {
CURLcode res;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
diff --git a/docs/libcurl/gnurl_easy_recv.3 b/docs/libcurl/gnurl_easy_recv.3
index d5127757f..abcc97457 100644
--- a/docs/libcurl/gnurl_easy_recv.3
+++ b/docs/libcurl/gnurl_easy_recv.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_easy_reset.3 b/docs/libcurl/gnurl_easy_reset.3
index 5bf6ddf9a..05b7b069f 100644
--- a/docs/libcurl/gnurl_easy_reset.3
+++ b/docs/libcurl/gnurl_easy_reset.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_easy_send.3 b/docs/libcurl/gnurl_easy_send.3
index 08c0671b0..91c1324d4 100644
--- a/docs/libcurl/gnurl_easy_send.3
+++ b/docs/libcurl/gnurl_easy_send.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_easy_setopt.3 b/docs/libcurl/gnurl_easy_setopt.3
index 6d6e3f842..848981927 100644
--- a/docs/libcurl/gnurl_easy_setopt.3
+++ b/docs/libcurl/gnurl_easy_setopt.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -48,7 +48,8 @@ thus the string storage associated to the pointer argument may be overwritten
after \fIcurl_easy_setopt(3)\fP returns. The only exception to this rule is
really \fICURLOPT_POSTFIELDS(3)\fP, but the alternative that copies the string
\fICURLOPT_COPYPOSTFIELDS(3)\fP has some usage characteristics you need to
-read up on.
+read up on. This function does not accept input strings longer than
+\fBCURL_MAX_INPUT_LENGTH\fP (8 MB).
The order in which the options are set does not matter.
@@ -319,6 +320,18 @@ Add or control cookies. See \fICURLOPT_COOKIELIST(3)\fP
Specify the Alt-Svc: cache file name. See \fICURLOPT_ALTSVC(3)\fP
.IP CURLOPT_ALTSVC_CTRL
Enable and configure Alt-Svc: treatment. See \fICURLOPT_ALTSVC_CTRL(3)\fP
+.IP CURLOPT_HSTS
+Set HSTS cache file. See \fICURLOPT_HSTS(3)\fP
+.IP CURLOPT_HSTS_CTRL
+Enable HSTS. See \fICURLOPT_HSTS_CTRL(3)\fP
+.IP CURLOPT_HSTSREADFUNCTION
+Set HSTS read callback. See \fICURLOPT_HSTSREADFUNCTION(3)\fP
+.IP CURLOPT_HSTSREADDATA
+Pass pointer to the HSTS read callback. See \fICURLOPT_HSTSREADDATA(3)\fP
+.IP CURLOPT_HSTSWRITEFUNCTION
+Set HSTS write callback. See \fICURLOPT_HSTSWRITEFUNCTION(3)\fP
+.IP CURLOPT_HSTSWRITEDATA
+Pass pointer to the HSTS write callback. See \fICURLOPT_HSTSWRITEDATA(3)\fP
.IP CURLOPT_HTTPGET
Do an HTTP GET request. See \fICURLOPT_HTTPGET(3)\fP
.IP CURLOPT_REQUEST_TARGET
@@ -532,6 +545,8 @@ Proxy client key type. See \fICURLOPT_PROXY_SSLKEYTYPE(3)\fP
Client key password. See \fICURLOPT_KEYPASSWD(3)\fP
.IP CURLOPT_PROXY_KEYPASSWD
Proxy client key password. See \fICURLOPT_PROXY_KEYPASSWD(3)\fP
+.IP CURLOPT_SSL_EC_CURVES
+Set key exchange curves. See \fICURLOPT_SSL_EC_CURVES(3)\fP
.IP CURLOPT_SSL_ENABLE_ALPN
Enable use of ALPN. See \fICURLOPT_SSL_ENABLE_ALPN(3)\fP
.IP CURLOPT_SSL_ENABLE_NPN
@@ -643,6 +658,9 @@ Strings passed on to libcurl must be shorter than 8000000 bytes, otherwise
\fIcurl_easy_setopt(3)\fP returns \fBCURLE_BAD_FUNCTION_ARGUMENT\fP (added in
7.65.0).
+\fBCURLE_BAD_FUNCTION_ARGUMENT\fP is returned when the argument to an option
+is invalid, like perhaps out of range.a
+
If you try to set an option that libcurl doesn't know about, perhaps because
the library is too old to support it or the option was removed in a recent
version, this function will return \fICURLE_UNKNOWN_OPTION\fP. If support for
@@ -653,7 +671,7 @@ the option was disabled at compile-time, it will return
CURL *curl = curl_easy_init();
if(curl) {
CURLcode res;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
diff --git a/docs/libcurl/gnurl_easy_strerror.3 b/docs/libcurl/gnurl_easy_strerror.3
index ec49d2cc0..5463f3830 100644
--- a/docs/libcurl/gnurl_easy_strerror.3
+++ b/docs/libcurl/gnurl_easy_strerror.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_easy_unescape.3 b/docs/libcurl/gnurl_easy_unescape.3
index 9841b4435..a997f2ef8 100644
--- a/docs/libcurl/gnurl_easy_unescape.3
+++ b/docs/libcurl/gnurl_easy_unescape.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_easy_upkeep.3 b/docs/libcurl/gnurl_easy_upkeep.3
index 761902381..9437959d8 100644
--- a/docs/libcurl/gnurl_easy_upkeep.3
+++ b/docs/libcurl/gnurl_easy_upkeep.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_escape.3 b/docs/libcurl/gnurl_escape.3
index c65392801..3a28d4fa4 100644
--- a/docs/libcurl/gnurl_escape.3
+++ b/docs/libcurl/gnurl_escape.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_formadd.3 b/docs/libcurl/gnurl_formadd.3
index e3a48e49d..581d551d0 100644
--- a/docs/libcurl/gnurl_formadd.3
+++ b/docs/libcurl/gnurl_formadd.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_formfree.3 b/docs/libcurl/gnurl_formfree.3
index 24764dc59..71df7e19a 100644
--- a/docs/libcurl/gnurl_formfree.3
+++ b/docs/libcurl/gnurl_formfree.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_formget.3 b/docs/libcurl/gnurl_formget.3
index 261e51df6..c9e43bd75 100644
--- a/docs/libcurl/gnurl_formget.3
+++ b/docs/libcurl/gnurl_formget.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_free.3 b/docs/libcurl/gnurl_free.3
index e9901fa74..e13e1b985 100644
--- a/docs/libcurl/gnurl_free.3
+++ b/docs/libcurl/gnurl_free.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_getdate.3 b/docs/libcurl/gnurl_getdate.3
index eb122eaf3..a29e485af 100644
--- a/docs/libcurl/gnurl_getdate.3
+++ b/docs/libcurl/gnurl_getdate.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_getenv.3 b/docs/libcurl/gnurl_getenv.3
index a953eba35..3d1f8929e 100644
--- a/docs/libcurl/gnurl_getenv.3
+++ b/docs/libcurl/gnurl_getenv.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_global_cleanup.3 b/docs/libcurl/gnurl_global_cleanup.3
index a5b6675c2..8fdfc1162 100644
--- a/docs/libcurl/gnurl_global_cleanup.3
+++ b/docs/libcurl/gnurl_global_cleanup.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_global_init.3 b/docs/libcurl/gnurl_global_init.3
index db84fad00..abc6d9b60 100644
--- a/docs/libcurl/gnurl_global_init.3
+++ b/docs/libcurl/gnurl_global_init.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_global_init_mem.3 b/docs/libcurl/gnurl_global_init_mem.3
index ddd64db7f..d3d1d9279 100644
--- a/docs/libcurl/gnurl_global_init_mem.3
+++ b/docs/libcurl/gnurl_global_init_mem.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_global_sslset.3 b/docs/libcurl/gnurl_global_sslset.3
index ed9c236d7..8cc67a234 100644
--- a/docs/libcurl/gnurl_global_sslset.3
+++ b/docs/libcurl/gnurl_global_sslset.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_mime_addpart.3 b/docs/libcurl/gnurl_mime_addpart.3
index 9aab787eb..330b28f71 100644
--- a/docs/libcurl/gnurl_mime_addpart.3
+++ b/docs/libcurl/gnurl_mime_addpart.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_mime_data.3 b/docs/libcurl/gnurl_mime_data.3
index 728826ab0..1cc4d2a10 100644
--- a/docs/libcurl/gnurl_mime_data.3
+++ b/docs/libcurl/gnurl_mime_data.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_mime_data_cb.3 b/docs/libcurl/gnurl_mime_data_cb.3
index 2fd7413c4..1eadf1e04 100644
--- a/docs/libcurl/gnurl_mime_data_cb.3
+++ b/docs/libcurl/gnurl_mime_data_cb.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_mime_encoder.3 b/docs/libcurl/gnurl_mime_encoder.3
index d0546b6b0..1026a679b 100644
--- a/docs/libcurl/gnurl_mime_encoder.3
+++ b/docs/libcurl/gnurl_mime_encoder.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_mime_filedata.3 b/docs/libcurl/gnurl_mime_filedata.3
index e89d22fea..deb0d4510 100644
--- a/docs/libcurl/gnurl_mime_filedata.3
+++ b/docs/libcurl/gnurl_mime_filedata.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_mime_filename.3 b/docs/libcurl/gnurl_mime_filename.3
index 6534a9ce5..a231545d5 100644
--- a/docs/libcurl/gnurl_mime_filename.3
+++ b/docs/libcurl/gnurl_mime_filename.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_mime_free.3 b/docs/libcurl/gnurl_mime_free.3
index 8476d1a32..4677c3f73 100644
--- a/docs/libcurl/gnurl_mime_free.3
+++ b/docs/libcurl/gnurl_mime_free.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_mime_headers.3 b/docs/libcurl/gnurl_mime_headers.3
index ae54efd81..0e9b365b7 100644
--- a/docs/libcurl/gnurl_mime_headers.3
+++ b/docs/libcurl/gnurl_mime_headers.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -50,7 +50,7 @@ CURLE_OK or a CURL error code upon failure.
.nf
struct curl_slist *headers = NULL;
- headers = curl_slist_append("Custom-Header: mooo", headers);
+ headers = curl_slist_append(headers, "Custom-Header: mooo");
/* use these headers, please take ownership */
curl_mime_headers(part, headers, TRUE);
diff --git a/docs/libcurl/gnurl_mime_init.3 b/docs/libcurl/gnurl_mime_init.3
index d6a49d1e7..e83df3874 100644
--- a/docs/libcurl/gnurl_mime_init.3
+++ b/docs/libcurl/gnurl_mime_init.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -56,7 +56,7 @@ A mime struct handle, or NULL upon failure.
/* Post and send it. */
curl_easy_setopt(easy, CURLOPT_MIMEPOST, mime);
- curl_easy_setopt(easy, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(easy, CURLOPT_URL, "https://example.com");
curl_easy_perform(easy);
/* Clean-up. */
diff --git a/docs/libcurl/gnurl_mime_name.3 b/docs/libcurl/gnurl_mime_name.3
index 79afe7515..a8504b112 100644
--- a/docs/libcurl/gnurl_mime_name.3
+++ b/docs/libcurl/gnurl_mime_name.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_mime_subparts.3 b/docs/libcurl/gnurl_mime_subparts.3
index ab57e6159..4f9883655 100644
--- a/docs/libcurl/gnurl_mime_subparts.3
+++ b/docs/libcurl/gnurl_mime_subparts.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_mime_type.3 b/docs/libcurl/gnurl_mime_type.3
index 1c1daae9b..29bbbf008 100644
--- a/docs/libcurl/gnurl_mime_type.3
+++ b/docs/libcurl/gnurl_mime_type.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_mprintf.3 b/docs/libcurl/gnurl_mprintf.3
index c34898afc..4a19e8cbf 100644
--- a/docs/libcurl/gnurl_mprintf.3
+++ b/docs/libcurl/gnurl_mprintf.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_multi_add_handle.3 b/docs/libcurl/gnurl_multi_add_handle.3
index c1d103f17..c8c230f34 100644
--- a/docs/libcurl/gnurl_multi_add_handle.3
+++ b/docs/libcurl/gnurl_multi_add_handle.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_multi_assign.3 b/docs/libcurl/gnurl_multi_assign.3
index 7cb2bf29b..395986966 100644
--- a/docs/libcurl/gnurl_multi_assign.3
+++ b/docs/libcurl/gnurl_multi_assign.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_multi_cleanup.3 b/docs/libcurl/gnurl_multi_cleanup.3
index cc3691137..6cb0537c2 100644
--- a/docs/libcurl/gnurl_multi_cleanup.3
+++ b/docs/libcurl/gnurl_multi_cleanup.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_multi_fdset.3 b/docs/libcurl/gnurl_multi_fdset.3
index 81fb4b1dc..74cb22511 100644
--- a/docs/libcurl/gnurl_multi_fdset.3
+++ b/docs/libcurl/gnurl_multi_fdset.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_multi_info_read.3 b/docs/libcurl/gnurl_multi_info_read.3
index daa754a9a..e89b30f8d 100644
--- a/docs/libcurl/gnurl_multi_info_read.3
+++ b/docs/libcurl/gnurl_multi_info_read.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_multi_init.3 b/docs/libcurl/gnurl_multi_init.3
index d06c12f4e..0b4f9e0ca 100644
--- a/docs/libcurl/gnurl_multi_init.3
+++ b/docs/libcurl/gnurl_multi_init.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_multi_perform.3 b/docs/libcurl/gnurl_multi_perform.3
index f59cc5e53..76fa3ff12 100644
--- a/docs/libcurl/gnurl_multi_perform.3
+++ b/docs/libcurl/gnurl_multi_perform.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_multi_poll.3 b/docs/libcurl/gnurl_multi_poll.3
index adab68d5e..37fcd7581 100644
--- a/docs/libcurl/gnurl_multi_poll.3
+++ b/docs/libcurl/gnurl_multi_poll.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_multi_remove_handle.3 b/docs/libcurl/gnurl_multi_remove_handle.3
index 0987ea287..9f7cc9e3b 100644
--- a/docs/libcurl/gnurl_multi_remove_handle.3
+++ b/docs/libcurl/gnurl_multi_remove_handle.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_multi_setopt.3 b/docs/libcurl/gnurl_multi_setopt.3
index dd141be0c..583274eab 100644
--- a/docs/libcurl/gnurl_multi_setopt.3
+++ b/docs/libcurl/gnurl_multi_setopt.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_multi_socket.3 b/docs/libcurl/gnurl_multi_socket.3
index 3ca76e668..01b801e89 100644
--- a/docs/libcurl/gnurl_multi_socket.3
+++ b/docs/libcurl/gnurl_multi_socket.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_multi_socket_action.3 b/docs/libcurl/gnurl_multi_socket_action.3
index 35b709231..419cc12fb 100644
--- a/docs/libcurl/gnurl_multi_socket_action.3
+++ b/docs/libcurl/gnurl_multi_socket_action.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_multi_strerror.3 b/docs/libcurl/gnurl_multi_strerror.3
index feb6cd684..24dbdb946 100644
--- a/docs/libcurl/gnurl_multi_strerror.3
+++ b/docs/libcurl/gnurl_multi_strerror.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_multi_timeout.3 b/docs/libcurl/gnurl_multi_timeout.3
index e2620dd8f..76e45ac25 100644
--- a/docs/libcurl/gnurl_multi_timeout.3
+++ b/docs/libcurl/gnurl_multi_timeout.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_multi_wait.3 b/docs/libcurl/gnurl_multi_wait.3
index 21c0842b4..64a7426a9 100644
--- a/docs/libcurl/gnurl_multi_wait.3
+++ b/docs/libcurl/gnurl_multi_wait.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_multi_wakeup.3 b/docs/libcurl/gnurl_multi_wakeup.3
index c47f85549..f029fb721 100644
--- a/docs/libcurl/gnurl_multi_wakeup.3
+++ b/docs/libcurl/gnurl_multi_wakeup.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_share_cleanup.3 b/docs/libcurl/gnurl_share_cleanup.3
index 9c07e0cbb..e3352573d 100644
--- a/docs/libcurl/gnurl_share_cleanup.3
+++ b/docs/libcurl/gnurl_share_cleanup.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_share_init.3 b/docs/libcurl/gnurl_share_init.3
index 4b479a614..954b10324 100644
--- a/docs/libcurl/gnurl_share_init.3
+++ b/docs/libcurl/gnurl_share_init.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_share_setopt.3 b/docs/libcurl/gnurl_share_setopt.3
index a446b6451..022211149 100644
--- a/docs/libcurl/gnurl_share_setopt.3
+++ b/docs/libcurl/gnurl_share_setopt.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_share_strerror.3 b/docs/libcurl/gnurl_share_strerror.3
index 5cb755742..b579298d5 100644
--- a/docs/libcurl/gnurl_share_strerror.3
+++ b/docs/libcurl/gnurl_share_strerror.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_slist_append.3 b/docs/libcurl/gnurl_slist_append.3
index 963ad760d..c76cb7881 100644
--- a/docs/libcurl/gnurl_slist_append.3
+++ b/docs/libcurl/gnurl_slist_append.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_slist_free_all.3 b/docs/libcurl/gnurl_slist_free_all.3
index bb9c522f7..30ab779fa 100644
--- a/docs/libcurl/gnurl_slist_free_all.3
+++ b/docs/libcurl/gnurl_slist_free_all.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_strequal.3 b/docs/libcurl/gnurl_strequal.3
index 4b7752cd7..3dab5cec2 100644
--- a/docs/libcurl/gnurl_strequal.3
+++ b/docs/libcurl/gnurl_strequal.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_unescape.3 b/docs/libcurl/gnurl_unescape.3
index c88b3947f..6fb54eb23 100644
--- a/docs/libcurl/gnurl_unescape.3
+++ b/docs/libcurl/gnurl_unescape.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_url.3 b/docs/libcurl/gnurl_url.3
index 325865ae2..68b6cd042 100644
--- a/docs/libcurl/gnurl_url.3
+++ b/docs/libcurl/gnurl_url.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_url_cleanup.3 b/docs/libcurl/gnurl_url_cleanup.3
index f0bfefdba..7452601f9 100644
--- a/docs/libcurl/gnurl_url_cleanup.3
+++ b/docs/libcurl/gnurl_url_cleanup.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_url_dup.3 b/docs/libcurl/gnurl_url_dup.3
index 7fa8d17c7..ea11af04e 100644
--- a/docs/libcurl/gnurl_url_dup.3
+++ b/docs/libcurl/gnurl_url_dup.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_url_get.3 b/docs/libcurl/gnurl_url_get.3
index 20edd1427..647e76432 100644
--- a/docs/libcurl/gnurl_url_get.3
+++ b/docs/libcurl/gnurl_url_get.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_url_set.3 b/docs/libcurl/gnurl_url_set.3
index 043ec38fb..23bc33279 100644
--- a/docs/libcurl/gnurl_url_set.3
+++ b/docs/libcurl/gnurl_url_set.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -126,7 +126,7 @@ A URL string passed on to \fIcurl_url_set(3)\fP for the \fBCURLUPART_URL\fP
part, must be shorter than 8000000 bytes otherwise it returns
\fBCURLUE_MALFORMED_INPUT\fP (added in 7.65.0).
-If this function returns an error, no URL part is returned.
+If this function returns an error, no URL part is set.
.SH EXAMPLE
.nf
CURLUcode rc;
diff --git a/docs/libcurl/gnurl_version.3 b/docs/libcurl/gnurl_version.3
index d08ef0bdc..5c4c28cb0 100644
--- a/docs/libcurl/gnurl_version.3
+++ b/docs/libcurl/gnurl_version.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/gnurl_version_info.3 b/docs/libcurl/gnurl_version_info.3
index 2e8ed2956..15042dc42 100644
--- a/docs/libcurl/gnurl_version_info.3
+++ b/docs/libcurl/gnurl_version_info.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -143,6 +143,9 @@ to use the current user credentials without the app having to pass them on.
(Added in 7.38.0)
.IP CURL_VERSION_GSSNEGOTIATE
supports HTTP GSS-Negotiate (added in 7.10.6)
+.IP CURL_VERSION_HSTS
+libcurl was built with support for HSTS (HTTP Strict Transport Security)
+(Added in 7.74.0)
.IP CURL_VERSION_HTTPS_PROXY
libcurl was built with support for HTTPS-proxy.
(Added in 7.52.0)
@@ -192,7 +195,8 @@ makes libcurl use Windows-provided functions for Kerberos, NTLM, SPNEGO and
Digest authentication. It also allows libcurl to use the current user
credentials without the app having to pass them on. (Added in 7.13.2)
.IP CURL_VERSION_TLSAUTH_SRP
-libcurl was built with support for TLS-SRP. (Added in 7.21.4)
+libcurl was built with support for TLS-SRP (in one or more of the built-in TLS
+backends). (Added in 7.21.4)
.IP CURL_VERSION_UNIX_SOCKETS
libcurl was built with support for Unix domain sockets.
(Added in 7.40.0)
diff --git a/docs/libcurl/libgnurl-easy.3 b/docs/libcurl/libgnurl-easy.3
index 7ba0b683e..0fe58159a 100644
--- a/docs/libcurl/libgnurl-easy.3
+++ b/docs/libcurl/libgnurl-easy.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/libgnurl-env.3 b/docs/libcurl/libgnurl-env.3
index 3807e662e..97ffde96d 100644
--- a/docs/libcurl/libgnurl-env.3
+++ b/docs/libcurl/libgnurl-env.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 2018 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -30,7 +30,7 @@ supports a set of additional environment variables independently of this.
.IP "[scheme]_proxy"
When libcurl is given a URL to use in a transfer, it first extracts the
"scheme" part from the URL and checks if there is a given proxy set for that
-in its corresponding environment variable. A URL like "http://example.com"
+in its corresponding environment variable. A URL like "https://example.com"
will hence use the "http_proxy" variable, while a URL like "ftp://example.com"
will use the "ftp_proxy" variable.
diff --git a/docs/libcurl/libgnurl-errors.3 b/docs/libcurl/libgnurl-errors.3
index c76535d0f..ae8c674e9 100644
--- a/docs/libcurl/libgnurl-errors.3
+++ b/docs/libcurl/libgnurl-errors.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/libgnurl-multi.3 b/docs/libcurl/libgnurl-multi.3
index 5176aebf0..77fe4c756 100644
--- a/docs/libcurl/libgnurl-multi.3
+++ b/docs/libcurl/libgnurl-multi.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/libgnurl-security.3 b/docs/libcurl/libgnurl-security.3
index f340facd3..705e2c7ef 100644
--- a/docs/libcurl/libgnurl-security.3
+++ b/docs/libcurl/libgnurl-security.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -154,7 +154,7 @@ behind a firewall. Applications can mitigate against this by using the
\fICURLOPT_FTP_SKIP_PASV_IP(3)\fP option or \fICURLOPT_FTPPORT(3)\fP.
Local servers sometimes assume local access comes from friends and trusted
-users. An application that expects http://example.com/file_to_read that and
+users. An application that expects https://example.com/file_to_read that and
instead gets http://192.168.0.1/my_router_config might print a file that would
otherwise be protected by the firewall.
@@ -348,7 +348,7 @@ plain HTTP connection.
.SH "Report Security Problems"
Should you detect or just suspect a security problem in libcurl or curl,
contact the project curl security team immediately. See
-https://curl.haxx.se/dev/secprocess.html for details.
+https://curl.se/dev/secprocess.html for details.
.SH "Showing What You Do"
Relatedly, be aware that in situations when you have problems with libcurl and
ask someone for help, everything you reveal in order to get best possible help
diff --git a/docs/libcurl/libgnurl-share.3 b/docs/libcurl/libgnurl-share.3
index 26e43b8c8..6f77c322c 100644
--- a/docs/libcurl/libgnurl-share.3
+++ b/docs/libcurl/libgnurl-share.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/libgnurl-thread.3 b/docs/libcurl/libgnurl-thread.3
index a85d0ca0d..ff9c2304f 100644
--- a/docs/libcurl/libgnurl-thread.3
+++ b/docs/libcurl/libgnurl-thread.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -51,7 +51,7 @@ OpenSSL <= 1.0.2 the user must set callbacks.
https://www.openssl.org/docs/man1.0.2/man3/CRYPTO_set_locking_callback.html#DESCRIPTION
-https://curl.haxx.se/libcurl/c/opensslthreadlock.html
+https://curl.se/libcurl/c/opensslthreadlock.html
.IP GnuTLS
https://gnutls.org/manual/html_node/Thread-safety.html
diff --git a/docs/libcurl/libgnurl-tutorial.3 b/docs/libcurl/libgnurl-tutorial.3
index c6f88d659..3aafcb853 100644
--- a/docs/libcurl/libgnurl-tutorial.3
+++ b/docs/libcurl/libgnurl-tutorial.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/libgnurl-url.3 b/docs/libcurl/libgnurl-url.3
index bdf82ec15..5b375131e 100644
--- a/docs/libcurl/libgnurl-url.3
+++ b/docs/libcurl/libgnurl-url.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/libgnurl.3 b/docs/libcurl/libgnurl.3
index d4ed70349..22bb82305 100644
--- a/docs/libcurl/libgnurl.3
+++ b/docs/libcurl/libgnurl.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/libgnurl.m4 b/docs/libcurl/libgnurl.m4
index c4f484813..036230c85 100644
--- a/docs/libcurl/libgnurl.m4
+++ b/docs/libcurl/libgnurl.m4
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/mksymbolsmanpage.pl b/docs/libcurl/mksymbolsmanpage.pl
index 7ac6fac88..b3609b4dd 100755
--- a/docs/libcurl/mksymbolsmanpage.pl
+++ b/docs/libcurl/mksymbolsmanpage.pl
@@ -10,7 +10,7 @@
# *
# * This software is licensed as described in the file COPYING, which
# * you should have received as part of this distribution. The terms
-# * are also available at https://curl.haxx.se/docs/copyright.html.
+# * are also available at https://curl.se/docs/copyright.html.
# *
# * You may opt to use, copy, modify, merge, publish, distribute and/or sell
# * copies of the Software, and permit persons to whom the Software is
@@ -39,7 +39,7 @@ print <<HEADER
.\\" *
.\\" * This software is licensed as described in the file COPYING, which
.\\" * you should have received as part of this distribution. The terms
-.\\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\\" * are also available at https://curl.se/docs/copyright.html.
.\\" *
.\\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/CMakeLists.txt b/docs/libcurl/opts/CMakeLists.txt
index 98acedf2a..d0035016d 100644
--- a/docs/libcurl/opts/CMakeLists.txt
+++ b/docs/libcurl/opts/CMakeLists.txt
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/CURLINFO_PROXY_ERROR.3 b/docs/libcurl/opts/CURLINFO_PROXY_ERROR.3
new file mode 100644
index 000000000..c7e168b44
--- /dev/null
+++ b/docs/libcurl/opts/CURLINFO_PROXY_ERROR.3
@@ -0,0 +1,104 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at https://curl.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH CURLINFO_PROXY_ERROR 3 "3 Aug 2020" "libcurl 7.73.0" "curl_easy_getinfo options"
+.SH NAME
+CURLINFO_PROXY_ERROR \- get the detailed (SOCKS) proxy error
+.SH SYNOPSIS
+.nf
+#include <curl/curl.h>
+
+typedef enum {
+ CURLPX_OK,
+ CURLPX_BAD_ADDRESS_TYPE,
+ CURLPX_BAD_VERSION,
+ CURLPX_CLOSED,
+ CURLPX_GSSAPI,
+ CURLPX_GSSAPI_PERMSG,
+ CURLPX_GSSAPI_PROTECTION,
+ CURLPX_IDENTD,
+ CURLPX_IDENTD_DIFFER,
+ CURLPX_LONG_HOSTNAME,
+ CURLPX_LONG_PASSWD,
+ CURLPX_LONG_USER,
+ CURLPX_NO_AUTH,
+ CURLPX_RECV_ADDRESS,
+ CURLPX_RECV_AUTH,
+ CURLPX_RECV_CONNECT,
+ CURLPX_RECV_REQACK,
+ CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED,
+ CURLPX_REPLY_COMMAND_NOT_SUPPORTED,
+ CURLPX_REPLY_CONNECTION_REFUSED,
+ CURLPX_REPLY_GENERAL_SERVER_FAILURE,
+ CURLPX_REPLY_HOST_UNREACHABLE,
+ CURLPX_REPLY_NETWORK_UNREACHABLE,
+ CURLPX_REPLY_NOT_ALLOWED,
+ CURLPX_REPLY_TTL_EXPIRED,
+ CURLPX_REPLY_UNASSIGNED,
+ CURLPX_REQUEST_FAILED,
+ CURLPX_RESOLVE_HOST,
+ CURLPX_SEND_AUTH,
+ CURLPX_SEND_CONNECT,
+ CURLPX_SEND_REQUEST,
+ CURLPX_UNKNOWN_FAIL,
+ CURLPX_UNKNOWN_MODE,
+ CURLPX_USER_REJECTED,
+ CURLPX_LAST /* never use */
+} CURLproxycode;
+
+CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_PROXY_ERROR, long *detail);
+.fi
+.SH DESCRIPTION
+Pass a pointer to a long to receive a detailed error code when the most recent
+transfer returned a CURLE_PROXY error.
+
+The return value will match the CURLproxycode set.
+
+The returned value will be zero (equal to CURLPX_OK) if no such response code
+was available.
+.SH PROTOCOLS
+All that can be done over SOCKS
+.SH EXAMPLE
+.nf
+CURL *curl = curl_easy_init();
+if(curl) {
+ CURLcode res;
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
+
+ curl_easy_setopt(curl, CURLOPT_PROXY, "socks5://127.0.0.1");
+ res = curl_easy_perform(curl);
+ if(res == CURLE_PROXY) {
+ long proxycode;
+ res = curl_easy_getinfo(curl, CURLINFO_PROXY_ERROR, &proxycode);
+ if(!res && proxycode)
+ printf("The detailed proxy error: %ld\\n", proxycode);
+ }
+ curl_easy_cleanup(curl);
+}
+.fi
+.SH AVAILABILITY
+Added in 7.73.0
+.SH RETURN VALUE
+Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
+.SH "SEE ALSO"
+.BR CURLINFO_RESPONSE_CODE "(3), " libcurl-errors "(3), "
+.BR curl_easy_getinfo "(3), " curl_easy_setopt "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_HSTS.3 b/docs/libcurl/opts/CURLOPT_HSTS.3
new file mode 100644
index 000000000..2eb366878
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_HSTS.3
@@ -0,0 +1,81 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at https://curl.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH CURLOPT_HSTS 3 "5 Feb 2019" "libcurl 7.74.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_HSTS \- set HSTS cache file name
+.SH SYNOPSIS
+.nf
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_HSTS, char *filename);
+.fi
+.SH EXPERIMENTAL
+Warning: this feature is early code and is marked as experimental. It can only
+be enabled by explicitly telling configure with \fB--enable-hsts\fP. You are
+advised to not ship this in production before the experimental label is
+removed.
+.SH DESCRIPTION
+Make the \fIfilename\fP point to a file name to load an existing HSTS cache
+from, and to store the cache in when the easy handle is closed. Setting a file
+name with this option will also enable HSTS for this handle (the equivalent of
+setting \fICURLHSTS_ENABLE\fP with \fICURLOPT_HSTS_CTRL(3)\fP).
+
+If the given file does not exist or contains no HSTS entries at startup, the
+HSTS cache will simply start empty. Setting the file name to NULL or "" will
+only enable HSTS without reading from or writing to any file.
+
+If this option is set multiple times, libcurl will load cache entries from
+each given file but will only store the last used name for later writing.
+.SH "FILE FORMAT"
+The HSTS cache is saved to and loaded from a text file with one entry per
+physical line. Each line in the file has the following format:
+
+[host] [stamp]
+
+[host] is the domain name for the entry and the name is dot-prefixed if it is
+a includeSubDomain entry (if the entry is valid for all subdmains to the name
+as well or only for the exact name).
+
+[stamp] is the time (in UTC) when the entry expires and it uses the format
+\&"YYYYMMDD HH:MM:SS".
+
+Lines starting with "#" are treated as comments and are ignored. There is
+currently no length or size limit.
+.SH DEFAULT
+NULL, no file name
+.SH PROTOCOLS
+HTTPS and HTTP
+.SH EXAMPLE
+.nf
+CURL *curl = curl_easy_init();
+if(curl) {
+ curl_easy_setopt(curl, CURLOPT_HSTS, "/home/user/.hsts-cache");
+ curl_easy_perform(curl);
+}
+.fi
+.SH AVAILABILITY
+Added in 7.74.0
+.SH RETURN VALUE
+Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
+.SH "SEE ALSO"
+.BR CURLOPT_HSTS_CTRL "(3), " CURLOPT_ALTSVC "(3), " CURLOPT_RESOLVE "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_HSTSREADDATA.3 b/docs/libcurl/opts/CURLOPT_HSTSREADDATA.3
new file mode 100644
index 000000000..5ae72d826
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_HSTSREADDATA.3
@@ -0,0 +1,66 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at https://curl.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH CURLOPT_HSTSREADDATA 3 "14 Sep 2020" "libcurl 7.74.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_HSTSREADDATA \- pointer passed to the HSTS read callback
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_HSTSREADDATA, void *pointer);
+.SH EXPERIMENTAL
+Warning: this feature is early code and is marked as experimental. It can only
+be enabled by explicitly telling configure with \fB--enable-hsts\fP. You are
+advised to not ship this in production before the experimental label is
+removed.
+.SH DESCRIPTION
+Data \fIpointer\fP to pass to the HSTS read function. If you use the
+\fICURLOPT_HSTSREADFUNCTION(3)\fP option, this is the pointer you'll get as
+input in the 3rd argument to the callback.
+
+This option doesn't enable HSTS, you need to use \fICURLOPT_HSTS_CTRL(3)\fP to
+do that.
+.SH DEFAULT
+NULL
+.SH PROTOCOLS
+This feature is only used for HTTP(S) transfer.
+.SH EXAMPLE
+.nf
+CURL *curl = curl_easy_init();
+struct MyData this;
+if(curl) {
+ curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+
+ /* pass pointer that gets passed in to the
+ CURLOPT_HSTSREADFUNCTION callback */
+ curl_easy_setopt(curl, CURLOPT_HSTSREADDATA, &this);
+
+ curl_easy_perform(curl);
+}
+.fi
+.SH AVAILABILITY
+Added in 7.74.0
+.SH RETURN VALUE
+This will return CURLE_OK.
+.SH "SEE ALSO"
+.BR CURLOPT_HSTSREADFUNCTION "(3), " CURLOPT_HSTSWRITEDATA "(3), "
+.BR CURLOPT_HSTSWRITEFUNCTION "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_HSTSREADFUNCTION.3 b/docs/libcurl/opts/CURLOPT_HSTSREADFUNCTION.3
new file mode 100644
index 000000000..c51df7983
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_HSTSREADFUNCTION.3
@@ -0,0 +1,81 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at https://curl.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH CURLOPT_HSTSREADFUNCTION 3 "14 Sep 2020" "libcurl 7.74.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_HSTSREADFUNCTION \- read callback for HSTS hosts
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLSTScode hstsread(CURL *easy, struct curl_hstsentry *sts, void *userp);
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_HSTSREADFUNCTION, hstsread);
+.SH EXPERIMENTAL
+Warning: this feature is early code and is marked as experimental. It can only
+be enabled by explicitly telling configure with \fB--enable-hsts\fP. You are
+advised to not ship this in production before the experimental label is
+removed.
+.SH DESCRIPTION
+Pass a pointer to your callback function, as the prototype shows above.
+
+This callback function gets called by libcurl repeatedly when it populates the
+in-memory HSTS cache.
+
+Set the \fIuserp\fP argument with the \fICURLOPT_HSTSREADDATA(3)\fP option or
+it will be NULL.
+
+When this callback is invoked, the \fIsts\fP pointer points to a populated
+struct: Copy the host name to 'name' (no longer than 'namelen' bytes). Make it
+null-terminated. Set 'includeSubDomains' to TRUE or FALSE. Set 'expire' to a
+date stamp or a zero length string for *forever* (wrong date stamp format
+might cause the name to not get accepted)
+
+The callback should return \fICURLSTS_OK\fP if it returns a name and is
+prepared to be called again (for another host) or \fICURLSTS_DONE\fP if it has
+no entry to return. It can also return \fICURLSTS_FAIL\fP to signal error.
+
+This option doesn't enable HSTS, you need to use \fICURLOPT_HSTS_CTRL(3)\fP to
+do that.
+.SH DEFAULT
+NULL - no callback.
+.SH PROTOCOLS
+This feature is only used for HTTP(S) transfer.
+.SH EXAMPLE
+.nf
+{
+ /* set HSTS read callback */
+ curl_easy_setopt(curl, CURLOPT_HSTSREADFUNCTION, hstsread);
+
+ /* pass in suitable argument to the callback */
+ curl_easy_setopt(curl, CURLOPT_HSTSREADDATA, &hstspreload[0]);
+
+ result = curl_easy_perform(curl);
+}
+.fi
+.SH AVAILABILITY
+Added in 7.74.0
+.SH RETURN VALUE
+This will return CURLE_OK.
+.SH "SEE ALSO"
+.BR CURLOPT_HSTSREADDATA "(3), " CURLOPT_HSTSWRITEFUNCTION "(3), "
+.BR CURLOPT_HSTS "(3), " CURLOPT_HSTS_CTRL "(3), "
+
diff --git a/docs/libcurl/opts/CURLOPT_HSTSWRITEDATA.3 b/docs/libcurl/opts/CURLOPT_HSTSWRITEDATA.3
new file mode 100644
index 000000000..68c50c24e
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_HSTSWRITEDATA.3
@@ -0,0 +1,66 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at https://curl.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH CURLOPT_HSTSWRITEDATA 3 "14 Sep 2020" "libcurl 7.74.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_HSTSWRITEDATA \- pointer passed to the HSTS write callback
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_HSTSWRITEDATA, void *pointer);
+.SH EXPERIMENTAL
+Warning: this feature is early code and is marked as experimental. It can only
+be enabled by explicitly telling configure with \fB--enable-hsts\fP. You are
+advised to not ship this in production before the experimental label is
+removed.
+.SH DESCRIPTION
+Data \fIpointer\fP to pass to the HSTS write function. If you use the
+\fICURLOPT_HSTSWRITEFUNCTION(3)\fP option, this is the pointer you'll get as
+input in the 4th argument to the callback.
+
+This option doesn't enable HSTS, you need to use \fICURLOPT_HSTS_CTRL(3)\fP to
+do that.
+.SH DEFAULT
+NULL
+.SH PROTOCOLS
+This feature is only used for HTTP(S) transfer.
+.SH EXAMPLE
+.nf
+CURL *curl = curl_easy_init();
+struct MyData this;
+if(curl) {
+ curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+
+ /* pass pointer that gets passed in to the
+ CURLOPT_HSTSWRITEFUNCTION callback */
+ curl_easy_setopt(curl, CURLOPT_HSTSWRITEDATA, &this);
+
+ curl_easy_perform(curl);
+}
+.fi
+.SH AVAILABILITY
+Added in 7.74.0
+.SH RETURN VALUE
+This will return CURLE_OK.
+.SH "SEE ALSO"
+.BR CURLOPT_HSTSWRITEFUNCTION "(3), " CURLOPT_HSTSREADDATA "(3), "
+.BR CURLOPT_HSTSREADFUNCTION "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_HSTSWRITEFUNCTION.3 b/docs/libcurl/opts/CURLOPT_HSTSWRITEFUNCTION.3
new file mode 100644
index 000000000..55b271c0b
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_HSTSWRITEFUNCTION.3
@@ -0,0 +1,79 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at https://curl.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH CURLOPT_HSTSWRITEFUNCTION 3 "14 Sep 2020" "libcurl 7.74.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_HSTSWRITEFUNCTION \- write callback for HSTS hosts
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLSTScode hstswrite(CURL *easy, struct curl_hstsentry *sts,
+ struct curl_index *count, void *userp);
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_HSTSWRITEFUNCTION, hstswrite);
+.SH EXPERIMENTAL
+Warning: this feature is early code and is marked as experimental. It can only
+be enabled by explicitly telling configure with \fB--enable-hsts\fP. You are
+advised to not ship this in production before the experimental label is
+removed.
+.SH DESCRIPTION
+Pass a pointer to your callback function, as the prototype shows above.
+
+This callback function gets called by libcurl repeatedly to allow the
+application to store the in-memory HSTS cache when libcurl is about to discard
+it.
+
+Set the \fIuserp\fP argument with the \fICURLOPT_HSTSWRITEDATA(3)\fP option or
+it will be NULL.
+
+When the callback is invoked, the \fIsts\fP pointer points to a populated
+struct: Read the host name to 'name' (it is 'namelen' bytes long and null
+terminated. The 'includeSubDomains' field is non-zero if the entry matches
+subdomains. The 'expire' string is a date stamp null-terminated string using
+the syntax YYYYMMDD HH:MM:SS.
+
+The callback should return \fICURLSTS_OK\fP if it succeeded and is prepared to
+be called again (for another host) or \fICURLSTS_DONE\fP if there's nothing
+more to do. It can also return \fICURLSTS_FAIL\fP to signal error.
+.SH DEFAULT
+NULL - no callback.
+.SH PROTOCOLS
+This feature is only used for HTTP(S) transfer.
+.SH EXAMPLE
+.nf
+{
+ /* set HSTS read callback */
+ curl_easy_setopt(curl, CURLOPT_HSTSWRITEFUNCTION, hstswrite);
+
+ /* pass in suitable argument to the callback */
+ curl_easy_setopt(curl, CURLOPT_HSTSWRITEDATA, &hstspreload[0]);
+
+ result = curl_easy_perform(curl);
+}
+.fi
+.SH AVAILABILITY
+Added in 7.74.0
+.SH RETURN VALUE
+This will return CURLE_OK.
+.SH "SEE ALSO"
+.BR CURLOPT_HSTSWRITEDATA "(3), " CURLOPT_HSTSWRITEFUNCTION "(3), "
+.BR CURLOPT_HSTS "(3), " CURLOPT_HSTS_CTRL "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_HSTS_CTRL.3 b/docs/libcurl/opts/CURLOPT_HSTS_CTRL.3
new file mode 100644
index 000000000..ecb7129f9
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_HSTS_CTRL.3
@@ -0,0 +1,73 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at https://curl.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH CURLOPT_HSTS_CTRL 3 "4 Sep 2020" "libcurl 7.74.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_HSTS_CTRL \- control HSTS behavior
+.SH SYNOPSIS
+.nf
+#include <curl/curl.h>
+
+#define CURLHSTS_ENABLE (1<<0)
+#define CURLHSTS_READONLYFILE (1<<1)
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_HSTS_CTRL, long bitmask);
+.fi
+.SH EXPERIMENTAL
+Warning: this feature is early code and is marked as experimental. It can only
+be enabled by explicitly telling configure with \fB--enable-hsts\fP. You are
+advised to not ship this in production before the experimental label is
+removed.
+.SH DESCRIPTION
+HSTS (HTTP Strict Transport Security) means that an HTTPS server can instruct
+the client to not contact it again over clear-text HTTP for a certain period
+into the future. libcurl will then automatically redirect HTTP attempts to
+such hosts to instead use HTTPS. This is done by libcurl retaining this
+knowledge in an in-memory cache.
+
+Populate the long \fIbitmask\fP with the correct set of features to instruct
+libcurl how to handle HSTS for the transfers using this handle.
+.SH BITS
+.IP "CURLHSTS_ENABLE"
+Enable the in-memory HSTS cache for this handle.
+.IP "CURLHSTS_READONLYFILE"
+Make the HSTS file (if specified) read-only - makes libcurl not save the cache
+to the file when closing the handle.
+.SH DEFAULT
+0. HSTS is disabled by default.
+.SH PROTOCOLS
+HTTPS and HTTP
+.SH EXAMPLE
+.nf
+CURL *curl = curl_easy_init();
+if(curl) {
+ curl_easy_setopt(curl, CURLOPT_HSTS_CTRL, CURLHSTS_ENABLE);
+ curl_easy_perform(curl);
+}
+.fi
+.SH AVAILABILITY
+Added in 7.74.0
+.SH RETURN VALUE
+Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
+.SH "SEE ALSO"
+.BR CURLOPT_HSTS "(3), " CURLOPT_CONNECT_TO "(3), " CURLOPT_RESOLVE "(3), "
+.BR CURLOPT_ALTSVC "(3), "
diff --git a/docs/libcurl/opts/CURLOPT_SSL_EC_CURVES.3 b/docs/libcurl/opts/CURLOPT_SSL_EC_CURVES.3
new file mode 100644
index 000000000..4ac98e599
--- /dev/null
+++ b/docs/libcurl/opts/CURLOPT_SSL_EC_CURVES.3
@@ -0,0 +1,54 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at https://curl.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH CURLOPT_SSL_EC_CURVES 3 "29 Aug 2020" "libcurl 7.73.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_SSL_EC_CURVES \- set key exchange curves
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_SSL_EC_CURVES, char *alg_list);
+.SH DESCRIPTION
+Pass a string as parameter with a colon delimited list of (EC) algorithms. This
+option defines the client's key exchange algorithms in the SSL handshake (if
+the SSL backend libcurl is built to use supports it).
+.SH DEFAULT
+"", embedded in SSL backend
+.SH PROTOCOLS
+HTTP
+.SH EXAMPLE
+.nf
+CURL *curl = curl_easy_init();
+if(curl) {
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
+ curl_easy_setopt(curl, CURLOPT_SSL_EC_CURVES, "X25519:P-521");
+ ret = curl_easy_perform(curl);
+ curl_easy_cleanup(curl);
+}
+.fi
+.SH AVAILABILITY
+Added in 7.73.0. Supported by the OpenSSL backend.
+.SH RETURN VALUE
+Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
+.SH "SEE ALSO"
+.BR CURLOPT_SSL_OPTIONS "(3), " CURLOPT_SSL_CIPHER_LIST "(3), "
+.BR CURLOPT_TLS13_CIPHERS "(3), "
diff --git a/docs/libcurl/opts/GNURLINFO_ACTIVESOCKET.3 b/docs/libcurl/opts/GNURLINFO_ACTIVESOCKET.3
index 3a3d54fa3..601e5d572 100644
--- a/docs/libcurl/opts/GNURLINFO_ACTIVESOCKET.3
+++ b/docs/libcurl/opts/GNURLINFO_ACTIVESOCKET.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -47,7 +47,7 @@ All
CURL *curl = curl_easy_init();
if(curl) {
curl_socket_t sockfd;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* Do not do the transfer - only connect to host */
curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L);
diff --git a/docs/libcurl/opts/GNURLINFO_APPCONNECT_TIME.3 b/docs/libcurl/opts/GNURLINFO_APPCONNECT_TIME.3
index 03ade4a3c..a99ecd555 100644
--- a/docs/libcurl/opts/GNURLINFO_APPCONNECT_TIME.3
+++ b/docs/libcurl/opts/GNURLINFO_APPCONNECT_TIME.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_APPCONNECT_TIME_T.3 b/docs/libcurl/opts/GNURLINFO_APPCONNECT_TIME_T.3
index 1ae9e6c9e..b192efc57 100644
--- a/docs/libcurl/opts/GNURLINFO_APPCONNECT_TIME_T.3
+++ b/docs/libcurl/opts/GNURLINFO_APPCONNECT_TIME_T.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_CERTINFO.3 b/docs/libcurl/opts/GNURLINFO_CERTINFO.3
index d3782fd39..7be8a24fc 100644
--- a/docs/libcurl/opts/GNURLINFO_CERTINFO.3
+++ b/docs/libcurl/opts/GNURLINFO_CERTINFO.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_CONDITION_UNMET.3 b/docs/libcurl/opts/GNURLINFO_CONDITION_UNMET.3
index dcd6fc0e5..c37d0530c 100644
--- a/docs/libcurl/opts/GNURLINFO_CONDITION_UNMET.3
+++ b/docs/libcurl/opts/GNURLINFO_CONDITION_UNMET.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -41,7 +41,7 @@ HTTP and some
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* January 1, 2020 is 1577833200 */
curl_easy_setopt(curl, CURLOPT_TIMEVALUE, 1577833200L);
diff --git a/docs/libcurl/opts/GNURLINFO_CONNECT_TIME.3 b/docs/libcurl/opts/GNURLINFO_CONNECT_TIME.3
index 651850cde..e94626aa6 100644
--- a/docs/libcurl/opts/GNURLINFO_CONNECT_TIME.3
+++ b/docs/libcurl/opts/GNURLINFO_CONNECT_TIME.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_CONNECT_TIME_T.3 b/docs/libcurl/opts/GNURLINFO_CONNECT_TIME_T.3
index 3479cc851..759f3a52a 100644
--- a/docs/libcurl/opts/GNURLINFO_CONNECT_TIME_T.3
+++ b/docs/libcurl/opts/GNURLINFO_CONNECT_TIME_T.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_DOWNLOAD.3 b/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_DOWNLOAD.3
index 639299337..8498f8fb6 100644
--- a/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_DOWNLOAD.3
+++ b/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_DOWNLOAD.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -41,7 +41,7 @@ HTTP(S)
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* Perform the request */
res = curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_DOWNLOAD_T.3 b/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_DOWNLOAD_T.3
index 74ca85049..99aad3842 100644
--- a/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_DOWNLOAD_T.3
+++ b/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_DOWNLOAD_T.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -38,7 +38,7 @@ HTTP(S)
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* Perform the request */
res = curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_UPLOAD.3 b/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_UPLOAD.3
index cd668e9eb..56a914b7a 100644
--- a/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_UPLOAD.3
+++ b/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_UPLOAD.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -40,7 +40,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* Perform the upload */
res = curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_UPLOAD_T.3 b/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_UPLOAD_T.3
index f6c033fb8..334e7058a 100644
--- a/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_UPLOAD_T.3
+++ b/docs/libcurl/opts/GNURLINFO_CONTENT_LENGTH_UPLOAD_T.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -37,7 +37,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* Perform the upload */
res = curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLINFO_CONTENT_TYPE.3 b/docs/libcurl/opts/GNURLINFO_CONTENT_TYPE.3
index a75a223fa..80fb69d56 100644
--- a/docs/libcurl/opts/GNURLINFO_CONTENT_TYPE.3
+++ b/docs/libcurl/opts/GNURLINFO_CONTENT_TYPE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -42,7 +42,7 @@ HTTP(S)
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
res = curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLINFO_COOKIELIST.3 b/docs/libcurl/opts/GNURLINFO_COOKIELIST.3
index e82ddb8a3..088392df7 100644
--- a/docs/libcurl/opts/GNURLINFO_COOKIELIST.3
+++ b/docs/libcurl/opts/GNURLINFO_COOKIELIST.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -43,7 +43,7 @@ HTTP(S)
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* enable the cookie engine */
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "");
diff --git a/docs/libcurl/opts/GNURLINFO_EFFECTIVE_METHOD.3 b/docs/libcurl/opts/GNURLINFO_EFFECTIVE_METHOD.3
index 57e45c26a..7b356c6dd 100644
--- a/docs/libcurl/opts/GNURLINFO_EFFECTIVE_METHOD.3
+++ b/docs/libcurl/opts/GNURLINFO_EFFECTIVE_METHOD.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -47,7 +47,7 @@ HTTP(S)
CURL *curl = curl_easy_init();
if(curl) {
CURLcode res;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "data");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
res = curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLINFO_EFFECTIVE_URL.3 b/docs/libcurl/opts/GNURLINFO_EFFECTIVE_URL.3
index ce9ec45f5..484641b58 100644
--- a/docs/libcurl/opts/GNURLINFO_EFFECTIVE_URL.3
+++ b/docs/libcurl/opts/GNURLINFO_EFFECTIVE_URL.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -43,7 +43,7 @@ HTTP(S)
CURL *curl = curl_easy_init();
if(curl) {
CURLcode res;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
res = curl_easy_perform(curl);
if(res == CURLE_OK) {
diff --git a/docs/libcurl/opts/GNURLINFO_FILETIME.3 b/docs/libcurl/opts/GNURLINFO_FILETIME.3
index b23b8afd2..c5c1d2ccf 100644
--- a/docs/libcurl/opts/GNURLINFO_FILETIME.3
+++ b/docs/libcurl/opts/GNURLINFO_FILETIME.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_FILETIME_T.3 b/docs/libcurl/opts/GNURLINFO_FILETIME_T.3
index 6ffd1a168..9cb2e209c 100644
--- a/docs/libcurl/opts/GNURLINFO_FILETIME_T.3
+++ b/docs/libcurl/opts/GNURLINFO_FILETIME_T.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_FTP_ENTRY_PATH.3 b/docs/libcurl/opts/GNURLINFO_FTP_ENTRY_PATH.3
index ee74c2c39..6bcd0ad3e 100644
--- a/docs/libcurl/opts/GNURLINFO_FTP_ENTRY_PATH.3
+++ b/docs/libcurl/opts/GNURLINFO_FTP_ENTRY_PATH.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_HEADER_SIZE.3 b/docs/libcurl/opts/GNURLINFO_HEADER_SIZE.3
index bc0418158..c9eb4ee3a 100644
--- a/docs/libcurl/opts/GNURLINFO_HEADER_SIZE.3
+++ b/docs/libcurl/opts/GNURLINFO_HEADER_SIZE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -40,7 +40,7 @@ All
CURL *curl = curl_easy_init();
if(curl) {
CURLcode res;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
res = curl_easy_perform(curl);
if(res == CURLE_OK) {
long size;
diff --git a/docs/libcurl/opts/GNURLINFO_HTTPAUTH_AVAIL.3 b/docs/libcurl/opts/GNURLINFO_HTTPAUTH_AVAIL.3
index 5d83d00ea..0cc2adacb 100644
--- a/docs/libcurl/opts/GNURLINFO_HTTPAUTH_AVAIL.3
+++ b/docs/libcurl/opts/GNURLINFO_HTTPAUTH_AVAIL.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -38,7 +38,7 @@ HTTP(S)
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
res = curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLINFO_HTTP_CONNECTCODE.3 b/docs/libcurl/opts/GNURLINFO_HTTP_CONNECTCODE.3
index 356ac2a88..3e47f2079 100644
--- a/docs/libcurl/opts/GNURLINFO_HTTP_CONNECTCODE.3
+++ b/docs/libcurl/opts/GNURLINFO_HTTP_CONNECTCODE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_HTTP_VERSION.3 b/docs/libcurl/opts/GNURLINFO_HTTP_VERSION.3
index caa43c725..f8f319888 100644
--- a/docs/libcurl/opts/GNURLINFO_HTTP_VERSION.3
+++ b/docs/libcurl/opts/GNURLINFO_HTTP_VERSION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -39,7 +39,7 @@ HTTP
CURL *curl = curl_easy_init();
if(curl) {
CURLcode res;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
res = curl_easy_perform(curl);
if(res == CURLE_OK) {
long http_version;
diff --git a/docs/libcurl/opts/GNURLINFO_LASTSOCKET.3 b/docs/libcurl/opts/GNURLINFO_LASTSOCKET.3
index f3e717220..70e44afef 100644
--- a/docs/libcurl/opts/GNURLINFO_LASTSOCKET.3
+++ b/docs/libcurl/opts/GNURLINFO_LASTSOCKET.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -47,7 +47,7 @@ All
CURL *curl = curl_easy_init();
if(curl) {
long sockfd; /* doesn't work on win64! */
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* Do not do the transfer - only connect to host */
curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L);
diff --git a/docs/libcurl/opts/GNURLINFO_LOCAL_IP.3 b/docs/libcurl/opts/GNURLINFO_LOCAL_IP.3
index a2fe9b736..78ccf85f7 100644
--- a/docs/libcurl/opts/GNURLINFO_LOCAL_IP.3
+++ b/docs/libcurl/opts/GNURLINFO_LOCAL_IP.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -45,7 +45,7 @@ All
{
char *ip;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLINFO_LOCAL_PORT.3 b/docs/libcurl/opts/GNURLINFO_LOCAL_PORT.3
index 9b10fd3ff..f197d3800 100644
--- a/docs/libcurl/opts/GNURLINFO_LOCAL_PORT.3
+++ b/docs/libcurl/opts/GNURLINFO_LOCAL_PORT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -40,7 +40,7 @@ All
curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
res = curl_easy_perform(curl);
if(CURLE_OK == res) {
diff --git a/docs/libcurl/opts/GNURLINFO_NAMELOOKUP_TIME.3 b/docs/libcurl/opts/GNURLINFO_NAMELOOKUP_TIME.3
index 52d374d1f..e3b0d1e4e 100644
--- a/docs/libcurl/opts/GNURLINFO_NAMELOOKUP_TIME.3
+++ b/docs/libcurl/opts/GNURLINFO_NAMELOOKUP_TIME.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_NAMELOOKUP_TIME_T.3 b/docs/libcurl/opts/GNURLINFO_NAMELOOKUP_TIME_T.3
index 542df9736..14b473737 100644
--- a/docs/libcurl/opts/GNURLINFO_NAMELOOKUP_TIME_T.3
+++ b/docs/libcurl/opts/GNURLINFO_NAMELOOKUP_TIME_T.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_NUM_CONNECTS.3 b/docs/libcurl/opts/GNURLINFO_NUM_CONNECTS.3
index 982f02241..d87c08ef5 100644
--- a/docs/libcurl/opts/GNURLINFO_NUM_CONNECTS.3
+++ b/docs/libcurl/opts/GNURLINFO_NUM_CONNECTS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -41,7 +41,7 @@ All
CURL *curl = curl_easy_init();
if(curl) {
CURLcode res;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
res = curl_easy_perform(curl);
if(res == CURLE_OK) {
diff --git a/docs/libcurl/opts/GNURLINFO_OS_ERRNO.3 b/docs/libcurl/opts/GNURLINFO_OS_ERRNO.3
index 2e987b1ae..8e9d1f587 100644
--- a/docs/libcurl/opts/GNURLINFO_OS_ERRNO.3
+++ b/docs/libcurl/opts/GNURLINFO_OS_ERRNO.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -38,7 +38,7 @@ All
CURL *curl = curl_easy_init();
if(curl) {
CURLcode res;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
res = curl_easy_perform(curl);
if(res != CURLE_OK) {
long error;
diff --git a/docs/libcurl/opts/GNURLINFO_PRETRANSFER_TIME.3 b/docs/libcurl/opts/GNURLINFO_PRETRANSFER_TIME.3
index 515293439..b0a1d6fb9 100644
--- a/docs/libcurl/opts/GNURLINFO_PRETRANSFER_TIME.3
+++ b/docs/libcurl/opts/GNURLINFO_PRETRANSFER_TIME.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_PRETRANSFER_TIME_T.3 b/docs/libcurl/opts/GNURLINFO_PRETRANSFER_TIME_T.3
index 1cccdef70..a00ed8395 100644
--- a/docs/libcurl/opts/GNURLINFO_PRETRANSFER_TIME_T.3
+++ b/docs/libcurl/opts/GNURLINFO_PRETRANSFER_TIME_T.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_PRIMARY_IP.3 b/docs/libcurl/opts/GNURLINFO_PRIMARY_IP.3
index 3100c2086..8466e70eb 100644
--- a/docs/libcurl/opts/GNURLINFO_PRIMARY_IP.3
+++ b/docs/libcurl/opts/GNURLINFO_PRIMARY_IP.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -44,7 +44,7 @@ All network based ones
{
char *ip;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLINFO_PRIMARY_PORT.3 b/docs/libcurl/opts/GNURLINFO_PRIMARY_PORT.3
index 44658e4c7..5a37b23d1 100644
--- a/docs/libcurl/opts/GNURLINFO_PRIMARY_PORT.3
+++ b/docs/libcurl/opts/GNURLINFO_PRIMARY_PORT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -37,7 +37,7 @@ All
CURL *curl = curl_easy_init();
if(curl) {
CURLcode res;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
res = curl_easy_perform(curl);
if(res == CURLE_OK) {
long port;
diff --git a/docs/libcurl/opts/GNURLINFO_PRIVATE.3 b/docs/libcurl/opts/GNURLINFO_PRIVATE.3
index 027ae245e..a0006e20c 100644
--- a/docs/libcurl/opts/GNURLINFO_PRIVATE.3
+++ b/docs/libcurl/opts/GNURLINFO_PRIVATE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -39,7 +39,7 @@ All
CURL *curl = curl_easy_init();
if(curl) {
void *pointer = 0x2345454;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
/* set the private pointer */
curl_easy_setopt(curl, CURLOPT_PRIVATE, pointer);
diff --git a/docs/libcurl/opts/GNURLINFO_PROTOCOL.3 b/docs/libcurl/opts/GNURLINFO_PROTOCOL.3
index ff6546379..e8430e5e4 100644
--- a/docs/libcurl/opts/GNURLINFO_PROTOCOL.3
+++ b/docs/libcurl/opts/GNURLINFO_PROTOCOL.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -46,7 +46,7 @@ All
CURL *curl = curl_easy_init();
if(curl) {
CURLcode res;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
res = curl_easy_perform(curl);
if(res == CURLE_OK) {
long protocol;
diff --git a/docs/libcurl/opts/GNURLINFO_PROXYAUTH_AVAIL.3 b/docs/libcurl/opts/GNURLINFO_PROXYAUTH_AVAIL.3
index 5a5064e09..437d45b46 100644
--- a/docs/libcurl/opts/GNURLINFO_PROXYAUTH_AVAIL.3
+++ b/docs/libcurl/opts/GNURLINFO_PROXYAUTH_AVAIL.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -38,7 +38,7 @@ HTTP(S)
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_setopt(curl, CURLOPT_PROXY, "http://127.0.0.1:80");
res = curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLINFO_PROXY_SSL_VERIFYRESULT.3 b/docs/libcurl/opts/GNURLINFO_PROXY_SSL_VERIFYRESULT.3
index 48d166c60..79da9ecb4 100644
--- a/docs/libcurl/opts/GNURLINFO_PROXY_SSL_VERIFYRESULT.3
+++ b/docs/libcurl/opts/GNURLINFO_PROXY_SSL_VERIFYRESULT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_REDIRECT_COUNT.3 b/docs/libcurl/opts/GNURLINFO_REDIRECT_COUNT.3
index 9cdce3897..0a52d2016 100644
--- a/docs/libcurl/opts/GNURLINFO_REDIRECT_COUNT.3
+++ b/docs/libcurl/opts/GNURLINFO_REDIRECT_COUNT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -37,7 +37,7 @@ HTTP(S)
CURL *curl = curl_easy_init();
if(curl) {
CURLcode res;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
res = curl_easy_perform(curl);
if(res == CURLE_OK) {
diff --git a/docs/libcurl/opts/GNURLINFO_REDIRECT_TIME.3 b/docs/libcurl/opts/GNURLINFO_REDIRECT_TIME.3
index 26f3f5117..d26a346a3 100644
--- a/docs/libcurl/opts/GNURLINFO_REDIRECT_TIME.3
+++ b/docs/libcurl/opts/GNURLINFO_REDIRECT_TIME.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_REDIRECT_TIME_T.3 b/docs/libcurl/opts/GNURLINFO_REDIRECT_TIME_T.3
index 093bbae1f..168f5d180 100644
--- a/docs/libcurl/opts/GNURLINFO_REDIRECT_TIME_T.3
+++ b/docs/libcurl/opts/GNURLINFO_REDIRECT_TIME_T.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_REDIRECT_URL.3 b/docs/libcurl/opts/GNURLINFO_REDIRECT_URL.3
index 6ba66d726..9bf35eb30 100644
--- a/docs/libcurl/opts/GNURLINFO_REDIRECT_URL.3
+++ b/docs/libcurl/opts/GNURLINFO_REDIRECT_URL.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -43,7 +43,7 @@ HTTP(S)
CURL *curl = curl_easy_init();
if(curl) {
CURLcode res;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
res = curl_easy_perform(curl);
if(res == CURLE_OK) {
char *url = NULL;
diff --git a/docs/libcurl/opts/GNURLINFO_REQUEST_SIZE.3 b/docs/libcurl/opts/GNURLINFO_REQUEST_SIZE.3
index 33606b0dd..2f85ffba5 100644
--- a/docs/libcurl/opts/GNURLINFO_REQUEST_SIZE.3
+++ b/docs/libcurl/opts/GNURLINFO_REQUEST_SIZE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -38,7 +38,7 @@ All
CURL *curl = curl_easy_init();
if(curl) {
CURLcode res;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
res = curl_easy_perform(curl);
if(res == CURLE_OK) {
long req;
diff --git a/docs/libcurl/opts/GNURLINFO_RESPONSE_CODE.3 b/docs/libcurl/opts/GNURLINFO_RESPONSE_CODE.3
index 9632fd837..e9ded3515 100644
--- a/docs/libcurl/opts/GNURLINFO_RESPONSE_CODE.3
+++ b/docs/libcurl/opts/GNURLINFO_RESPONSE_CODE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -42,7 +42,7 @@ HTTP, FTP and SMTP
CURL *curl = curl_easy_init();
if(curl) {
CURLcode res;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
res = curl_easy_perform(curl);
if(res == CURLE_OK) {
long response_code;
diff --git a/docs/libcurl/opts/GNURLINFO_RETRY_AFTER.3 b/docs/libcurl/opts/GNURLINFO_RETRY_AFTER.3
index 785c6b4df..eede14931 100644
--- a/docs/libcurl/opts/GNURLINFO_RETRY_AFTER.3
+++ b/docs/libcurl/opts/GNURLINFO_RETRY_AFTER.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -29,7 +29,7 @@ CURLINFO_RETRY_AFTER \- returns the Retry-After retry delay
CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_RETRY_AFTER, curl_off_t *retry);
.SH DESCRIPTION
Pass a pointer to a curl_off_t variable to receive the number of seconds the
-HTTP server suggesets the client should wait until the next request is
+HTTP server suggests the client should wait until the next request is
issued. The information from the "Retry-After:" header.
While the HTTP header might contain a fixed date string, the
@@ -44,7 +44,7 @@ HTTP(S)
CURL *curl = curl_easy_init();
if(curl) {
CURLcode res;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
res = curl_easy_perform(curl);
if(res == CURLE_OK) {
curl_off_t wait = 0;
diff --git a/docs/libcurl/opts/GNURLINFO_RTSP_CLIENT_CSEQ.3 b/docs/libcurl/opts/GNURLINFO_RTSP_CLIENT_CSEQ.3
index 2efeb618a..1f163187c 100644
--- a/docs/libcurl/opts/GNURLINFO_RTSP_CLIENT_CSEQ.3
+++ b/docs/libcurl/opts/GNURLINFO_RTSP_CLIENT_CSEQ.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_RTSP_CSEQ_RECV.3 b/docs/libcurl/opts/GNURLINFO_RTSP_CSEQ_RECV.3
index added9c70..1ff4fd09f 100644
--- a/docs/libcurl/opts/GNURLINFO_RTSP_CSEQ_RECV.3
+++ b/docs/libcurl/opts/GNURLINFO_RTSP_CSEQ_RECV.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_RTSP_SERVER_CSEQ.3 b/docs/libcurl/opts/GNURLINFO_RTSP_SERVER_CSEQ.3
index 88abb0709..82b1a6b59 100644
--- a/docs/libcurl/opts/GNURLINFO_RTSP_SERVER_CSEQ.3
+++ b/docs/libcurl/opts/GNURLINFO_RTSP_SERVER_CSEQ.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_RTSP_SESSION_ID.3 b/docs/libcurl/opts/GNURLINFO_RTSP_SESSION_ID.3
index c2a2df18e..dc66fee4c 100644
--- a/docs/libcurl/opts/GNURLINFO_RTSP_SESSION_ID.3
+++ b/docs/libcurl/opts/GNURLINFO_RTSP_SESSION_ID.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_SCHEME.3 b/docs/libcurl/opts/GNURLINFO_SCHEME.3
index 13f0a023a..8c983d04d 100644
--- a/docs/libcurl/opts/GNURLINFO_SCHEME.3
+++ b/docs/libcurl/opts/GNURLINFO_SCHEME.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -42,7 +42,7 @@ All
CURL *curl = curl_easy_init();
if(curl) {
CURLcode res;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
res = curl_easy_perform(curl);
if(res == CURLE_OK) {
char *scheme = NULL;
diff --git a/docs/libcurl/opts/GNURLINFO_SIZE_DOWNLOAD.3 b/docs/libcurl/opts/GNURLINFO_SIZE_DOWNLOAD.3
index f3c224fd6..d849103e3 100644
--- a/docs/libcurl/opts/GNURLINFO_SIZE_DOWNLOAD.3
+++ b/docs/libcurl/opts/GNURLINFO_SIZE_DOWNLOAD.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -42,7 +42,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* Perform the request */
res = curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLINFO_SIZE_DOWNLOAD_T.3 b/docs/libcurl/opts/GNURLINFO_SIZE_DOWNLOAD_T.3
index bee15f477..ac17a10ec 100644
--- a/docs/libcurl/opts/GNURLINFO_SIZE_DOWNLOAD_T.3
+++ b/docs/libcurl/opts/GNURLINFO_SIZE_DOWNLOAD_T.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -39,7 +39,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* Perform the request */
res = curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLINFO_SIZE_UPLOAD.3 b/docs/libcurl/opts/GNURLINFO_SIZE_UPLOAD.3
index 3915385ac..80e2cced5 100644
--- a/docs/libcurl/opts/GNURLINFO_SIZE_UPLOAD.3
+++ b/docs/libcurl/opts/GNURLINFO_SIZE_UPLOAD.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -39,7 +39,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* Perform the request */
res = curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLINFO_SIZE_UPLOAD_T.3 b/docs/libcurl/opts/GNURLINFO_SIZE_UPLOAD_T.3
index d042d7d7e..727a01013 100644
--- a/docs/libcurl/opts/GNURLINFO_SIZE_UPLOAD_T.3
+++ b/docs/libcurl/opts/GNURLINFO_SIZE_UPLOAD_T.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -36,7 +36,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* Perform the request */
res = curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLINFO_SPEED_DOWNLOAD.3 b/docs/libcurl/opts/GNURLINFO_SPEED_DOWNLOAD.3
index b30e1c183..93c5238d8 100644
--- a/docs/libcurl/opts/GNURLINFO_SPEED_DOWNLOAD.3
+++ b/docs/libcurl/opts/GNURLINFO_SPEED_DOWNLOAD.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -38,7 +38,7 @@ sensible variable type.
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* Perform the request */
res = curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLINFO_SPEED_DOWNLOAD_T.3 b/docs/libcurl/opts/GNURLINFO_SPEED_DOWNLOAD_T.3
index 2c574b44e..f963d9029 100644
--- a/docs/libcurl/opts/GNURLINFO_SPEED_DOWNLOAD_T.3
+++ b/docs/libcurl/opts/GNURLINFO_SPEED_DOWNLOAD_T.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -35,7 +35,7 @@ that curl measured for the complete download. Measured in bytes/second.
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* Perform the request */
res = curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLINFO_SPEED_UPLOAD.3 b/docs/libcurl/opts/GNURLINFO_SPEED_UPLOAD.3
index 5ab3d92fe..775091e96 100644
--- a/docs/libcurl/opts/GNURLINFO_SPEED_UPLOAD.3
+++ b/docs/libcurl/opts/GNURLINFO_SPEED_UPLOAD.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -38,7 +38,7 @@ sensible variable type.
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* Perform the request */
res = curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLINFO_SPEED_UPLOAD_T.3 b/docs/libcurl/opts/GNURLINFO_SPEED_UPLOAD_T.3
index 7959222d3..c8ada230a 100644
--- a/docs/libcurl/opts/GNURLINFO_SPEED_UPLOAD_T.3
+++ b/docs/libcurl/opts/GNURLINFO_SPEED_UPLOAD_T.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -35,7 +35,7 @@ curl measured for the complete upload. Measured in bytes/second.
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* Perform the request */
res = curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLINFO_SSL_ENGINES.3 b/docs/libcurl/opts/GNURLINFO_SSL_ENGINES.3
index 9a0120bdf..640cc0ebc 100644
--- a/docs/libcurl/opts/GNURLINFO_SSL_ENGINES.3
+++ b/docs/libcurl/opts/GNURLINFO_SSL_ENGINES.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_SSL_VERIFYRESULT.3 b/docs/libcurl/opts/GNURLINFO_SSL_VERIFYRESULT.3
index 5b4d64341..a71efe758 100644
--- a/docs/libcurl/opts/GNURLINFO_SSL_VERIFYRESULT.3
+++ b/docs/libcurl/opts/GNURLINFO_SSL_VERIFYRESULT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_STARTTRANSFER_TIME.3 b/docs/libcurl/opts/GNURLINFO_STARTTRANSFER_TIME.3
index 6ac4707c8..0335846f9 100644
--- a/docs/libcurl/opts/GNURLINFO_STARTTRANSFER_TIME.3
+++ b/docs/libcurl/opts/GNURLINFO_STARTTRANSFER_TIME.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_STARTTRANSFER_TIME_T.3 b/docs/libcurl/opts/GNURLINFO_STARTTRANSFER_TIME_T.3
index db71fd8e2..da8e17e9e 100644
--- a/docs/libcurl/opts/GNURLINFO_STARTTRANSFER_TIME_T.3
+++ b/docs/libcurl/opts/GNURLINFO_STARTTRANSFER_TIME_T.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_TLS_SESSION.3 b/docs/libcurl/opts/GNURLINFO_TLS_SESSION.3
index 293fb0217..0ad56e4ab 100644
--- a/docs/libcurl/opts/GNURLINFO_TLS_SESSION.3
+++ b/docs/libcurl/opts/GNURLINFO_TLS_SESSION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_TLS_SSL_PTR.3 b/docs/libcurl/opts/GNURLINFO_TLS_SSL_PTR.3
index c4674e75b..99129fb77 100644
--- a/docs/libcurl/opts/GNURLINFO_TLS_SSL_PTR.3
+++ b/docs/libcurl/opts/GNURLINFO_TLS_SSL_PTR.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_TOTAL_TIME.3 b/docs/libcurl/opts/GNURLINFO_TOTAL_TIME.3
index bab982cdc..54d334b2a 100644
--- a/docs/libcurl/opts/GNURLINFO_TOTAL_TIME.3
+++ b/docs/libcurl/opts/GNURLINFO_TOTAL_TIME.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLINFO_TOTAL_TIME_T.3 b/docs/libcurl/opts/GNURLINFO_TOTAL_TIME_T.3
index 70cd7e567..330cd34ca 100644
--- a/docs/libcurl/opts/GNURLINFO_TOTAL_TIME_T.3
+++ b/docs/libcurl/opts/GNURLINFO_TOTAL_TIME_T.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLMOPT_CHUNK_LENGTH_PENALTY_SIZE.3 b/docs/libcurl/opts/GNURLMOPT_CHUNK_LENGTH_PENALTY_SIZE.3
index 4da4fed01..e30fd84e3 100644
--- a/docs/libcurl/opts/GNURLMOPT_CHUNK_LENGTH_PENALTY_SIZE.3
+++ b/docs/libcurl/opts/GNURLMOPT_CHUNK_LENGTH_PENALTY_SIZE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLMOPT_CONTENT_LENGTH_PENALTY_SIZE.3 b/docs/libcurl/opts/GNURLMOPT_CONTENT_LENGTH_PENALTY_SIZE.3
index 884cb1d72..3c9201c6d 100644
--- a/docs/libcurl/opts/GNURLMOPT_CONTENT_LENGTH_PENALTY_SIZE.3
+++ b/docs/libcurl/opts/GNURLMOPT_CONTENT_LENGTH_PENALTY_SIZE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLMOPT_MAXCONNECTS.3 b/docs/libcurl/opts/GNURLMOPT_MAXCONNECTS.3
index 942918aca..14cc849fa 100644
--- a/docs/libcurl/opts/GNURLMOPT_MAXCONNECTS.3
+++ b/docs/libcurl/opts/GNURLMOPT_MAXCONNECTS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLMOPT_MAX_CONCURRENT_STREAMS.3 b/docs/libcurl/opts/GNURLMOPT_MAX_CONCURRENT_STREAMS.3
index 3e59209ad..ced56abfd 100644
--- a/docs/libcurl/opts/GNURLMOPT_MAX_CONCURRENT_STREAMS.3
+++ b/docs/libcurl/opts/GNURLMOPT_MAX_CONCURRENT_STREAMS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLMOPT_MAX_HOST_CONNECTIONS.3 b/docs/libcurl/opts/GNURLMOPT_MAX_HOST_CONNECTIONS.3
index 13455c71b..d2b9290c7 100644
--- a/docs/libcurl/opts/GNURLMOPT_MAX_HOST_CONNECTIONS.3
+++ b/docs/libcurl/opts/GNURLMOPT_MAX_HOST_CONNECTIONS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLMOPT_MAX_PIPELINE_LENGTH.3 b/docs/libcurl/opts/GNURLMOPT_MAX_PIPELINE_LENGTH.3
index 63a856a3b..de0d7095f 100644
--- a/docs/libcurl/opts/GNURLMOPT_MAX_PIPELINE_LENGTH.3
+++ b/docs/libcurl/opts/GNURLMOPT_MAX_PIPELINE_LENGTH.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLMOPT_MAX_TOTAL_CONNECTIONS.3 b/docs/libcurl/opts/GNURLMOPT_MAX_TOTAL_CONNECTIONS.3
index 733ba0293..45733cd6f 100644
--- a/docs/libcurl/opts/GNURLMOPT_MAX_TOTAL_CONNECTIONS.3
+++ b/docs/libcurl/opts/GNURLMOPT_MAX_TOTAL_CONNECTIONS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLMOPT_PIPELINING.3 b/docs/libcurl/opts/GNURLMOPT_PIPELINING.3
index 95d0aad05..3e71a23e4 100644
--- a/docs/libcurl/opts/GNURLMOPT_PIPELINING.3
+++ b/docs/libcurl/opts/GNURLMOPT_PIPELINING.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLMOPT_PIPELINING_SERVER_BL.3 b/docs/libcurl/opts/GNURLMOPT_PIPELINING_SERVER_BL.3
index 46bce5f63..47c142854 100644
--- a/docs/libcurl/opts/GNURLMOPT_PIPELINING_SERVER_BL.3
+++ b/docs/libcurl/opts/GNURLMOPT_PIPELINING_SERVER_BL.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLMOPT_PIPELINING_SITE_BL.3 b/docs/libcurl/opts/GNURLMOPT_PIPELINING_SITE_BL.3
index ab42861e3..5856d43a1 100644
--- a/docs/libcurl/opts/GNURLMOPT_PIPELINING_SITE_BL.3
+++ b/docs/libcurl/opts/GNURLMOPT_PIPELINING_SITE_BL.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLMOPT_PUSHDATA.3 b/docs/libcurl/opts/GNURLMOPT_PUSHDATA.3
index 82ec928ae..5f6586a5c 100644
--- a/docs/libcurl/opts/GNURLMOPT_PUSHDATA.3
+++ b/docs/libcurl/opts/GNURLMOPT_PUSHDATA.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLMOPT_PUSHFUNCTION.3 b/docs/libcurl/opts/GNURLMOPT_PUSHFUNCTION.3
index b9d5efcdc..5c15f9973 100644
--- a/docs/libcurl/opts/GNURLMOPT_PUSHFUNCTION.3
+++ b/docs/libcurl/opts/GNURLMOPT_PUSHFUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLMOPT_SOCKETDATA.3 b/docs/libcurl/opts/GNURLMOPT_SOCKETDATA.3
index 10bff8bd7..2f1a9a1cc 100644
--- a/docs/libcurl/opts/GNURLMOPT_SOCKETDATA.3
+++ b/docs/libcurl/opts/GNURLMOPT_SOCKETDATA.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLMOPT_SOCKETFUNCTION.3 b/docs/libcurl/opts/GNURLMOPT_SOCKETFUNCTION.3
index cd7b49dce..dd70220b4 100644
--- a/docs/libcurl/opts/GNURLMOPT_SOCKETFUNCTION.3
+++ b/docs/libcurl/opts/GNURLMOPT_SOCKETFUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLMOPT_TIMERDATA.3 b/docs/libcurl/opts/GNURLMOPT_TIMERDATA.3
index 29ad19160..0e54ed23c 100644
--- a/docs/libcurl/opts/GNURLMOPT_TIMERDATA.3
+++ b/docs/libcurl/opts/GNURLMOPT_TIMERDATA.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLMOPT_TIMERFUNCTION.3 b/docs/libcurl/opts/GNURLMOPT_TIMERFUNCTION.3
index 1e2d64862..46d5b5157 100644
--- a/docs/libcurl/opts/GNURLMOPT_TIMERFUNCTION.3
+++ b/docs/libcurl/opts/GNURLMOPT_TIMERFUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_ABSTRACT_UNIX_SOCKET.3 b/docs/libcurl/opts/GNURLOPT_ABSTRACT_UNIX_SOCKET.3
index fbb25c4f6..ccb644a16 100644
--- a/docs/libcurl/opts/GNURLOPT_ABSTRACT_UNIX_SOCKET.3
+++ b/docs/libcurl/opts/GNURLOPT_ABSTRACT_UNIX_SOCKET.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_ACCEPTTIMEOUT_MS.3 b/docs/libcurl/opts/GNURLOPT_ACCEPTTIMEOUT_MS.3
index d74e14960..2c1e09df4 100644
--- a/docs/libcurl/opts/GNURLOPT_ACCEPTTIMEOUT_MS.3
+++ b/docs/libcurl/opts/GNURLOPT_ACCEPTTIMEOUT_MS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_ACCEPT_ENCODING.3 b/docs/libcurl/opts/GNURLOPT_ACCEPT_ENCODING.3
index 2586b013d..f2be9198d 100644
--- a/docs/libcurl/opts/GNURLOPT_ACCEPT_ENCODING.3
+++ b/docs/libcurl/opts/GNURLOPT_ACCEPT_ENCODING.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -82,7 +82,7 @@ HTTP
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* enable all supported built-in compressions */
curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "");
diff --git a/docs/libcurl/opts/GNURLOPT_ADDRESS_SCOPE.3 b/docs/libcurl/opts/GNURLOPT_ADDRESS_SCOPE.3
index 75467fe20..706a24e4e 100644
--- a/docs/libcurl/opts/GNURLOPT_ADDRESS_SCOPE.3
+++ b/docs/libcurl/opts/GNURLOPT_ADDRESS_SCOPE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_ALTSVC.3 b/docs/libcurl/opts/GNURLOPT_ALTSVC.3
index d1d44629e..9ba1e7ef0 100644
--- a/docs/libcurl/opts/GNURLOPT_ALTSVC.3
+++ b/docs/libcurl/opts/GNURLOPT_ALTSVC.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -29,11 +29,6 @@ CURLOPT_ALTSVC \- set alt-svc cache file name
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_ALTSVC, char *filename);
.fi
-.SH EXPERIMENTAL
-Warning: this feature is early code and is marked as experimental. It can only
-be enabled by explicitly telling configure with \fB--enable-alt-svc\fP. You are
-advised to not ship this in production before the experimental label is
-removed.
.SH DESCRIPTION
Pass in a pointer to a \fIfilename\fP to instruct libcurl to use that file as
the Alt-Svc cache to read existing cache contents from and possibly also write
diff --git a/docs/libcurl/opts/GNURLOPT_ALTSVC_CTRL.3 b/docs/libcurl/opts/GNURLOPT_ALTSVC_CTRL.3
index 287da646e..6dc10bbc1 100644
--- a/docs/libcurl/opts/GNURLOPT_ALTSVC_CTRL.3
+++ b/docs/libcurl/opts/GNURLOPT_ALTSVC_CTRL.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -27,7 +27,6 @@ CURLOPT_ALTSVC_CTRL \- control alt-svc behavior
.nf
#include <gnurl/curl.h>
-#define CURLALTSVC_IMMEDIATELY (1<<0)
#define CURLALTSVC_READONLYFILE (1<<2)
#define CURLALTSVC_H1 (1<<3)
#define CURLALTSVC_H2 (1<<4)
@@ -35,11 +34,6 @@ CURLOPT_ALTSVC_CTRL \- control alt-svc behavior
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_ALTSVC_CTRL, long bitmask);
.fi
-.SH EXPERIMENTAL
-Warning: this feature is early code and is marked as experimental. It can only
-be enabled by explicitly telling configure with \fB--enable-alt-svc\fP. You are
-advised to not ship this in production before the experimental label is
-removed.
.SH DESCRIPTION
Populate the long \fIbitmask\fP with the correct set of features to instruct
libcurl how to handle Alt-Svc for the transfers using this handle.
@@ -50,10 +44,6 @@ origin is properly hosted over HTTPS. These requirements are there to make
sure both the source and the destination are legitimate.
Setting any bit will enable the alt-svc engine.
-.IP "CURLALTSVC_IMMEDIATELY"
-If an Alt-Svc: header is received, this instructs libcurl to switch to one of
-those alternatives asap rather than to save it and use for the next
-request. (Not currently supported).
.IP "CURLALTSVC_READONLYFILE"
Do not write the alt-svc cache back to the file specified with
\fICURLOPT_ALTSVC(3)\fP even if it gets updated. By default a file specified
diff --git a/docs/libcurl/opts/GNURLOPT_APPEND.3 b/docs/libcurl/opts/GNURLOPT_APPEND.3
index 69e293191..65eee1ea1 100644
--- a/docs/libcurl/opts/GNURLOPT_APPEND.3
+++ b/docs/libcurl/opts/GNURLOPT_APPEND.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_AUTOREFERER.3 b/docs/libcurl/opts/GNURLOPT_AUTOREFERER.3
index 9f0f2f527..77ab5ec1f 100644
--- a/docs/libcurl/opts/GNURLOPT_AUTOREFERER.3
+++ b/docs/libcurl/opts/GNURLOPT_AUTOREFERER.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -39,7 +39,7 @@ HTTP
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
/* follow redirects */
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
diff --git a/docs/libcurl/opts/GNURLOPT_BUFFERSIZE.3 b/docs/libcurl/opts/GNURLOPT_BUFFERSIZE.3
index 1607d02de..240fd5d02 100644
--- a/docs/libcurl/opts/GNURLOPT_BUFFERSIZE.3
+++ b/docs/libcurl/opts/GNURLOPT_BUFFERSIZE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_CAINFO.3 b/docs/libcurl/opts/GNURLOPT_CAINFO.3
index 83a86a643..44ae70232 100644
--- a/docs/libcurl/opts/GNURLOPT_CAINFO.3
+++ b/docs/libcurl/opts/GNURLOPT_CAINFO.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_CAPATH.3 b/docs/libcurl/opts/GNURLOPT_CAPATH.3
index 17ff2fb47..bf089b109 100644
--- a/docs/libcurl/opts/GNURLOPT_CAPATH.3
+++ b/docs/libcurl/opts/GNURLOPT_CAPATH.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_CERTINFO.3 b/docs/libcurl/opts/GNURLOPT_CERTINFO.3
index 0aba17e7c..a3d074616 100644
--- a/docs/libcurl/opts/GNURLOPT_CERTINFO.3
+++ b/docs/libcurl/opts/GNURLOPT_CERTINFO.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_CHUNK_BGN_FUNCTION.3 b/docs/libcurl/opts/GNURLOPT_CHUNK_BGN_FUNCTION.3
index a4ca84936..6f14562ea 100644
--- a/docs/libcurl/opts/GNURLOPT_CHUNK_BGN_FUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_CHUNK_BGN_FUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_CHUNK_DATA.3 b/docs/libcurl/opts/GNURLOPT_CHUNK_DATA.3
index 04572f405..3fdc26bf0 100644
--- a/docs/libcurl/opts/GNURLOPT_CHUNK_DATA.3
+++ b/docs/libcurl/opts/GNURLOPT_CHUNK_DATA.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_CHUNK_END_FUNCTION.3 b/docs/libcurl/opts/GNURLOPT_CHUNK_END_FUNCTION.3
index d99d53e2e..69322bf68 100644
--- a/docs/libcurl/opts/GNURLOPT_CHUNK_END_FUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_CHUNK_END_FUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_CLOSESOCKETDATA.3 b/docs/libcurl/opts/GNURLOPT_CLOSESOCKETDATA.3
index dd9e69594..7772996d6 100644
--- a/docs/libcurl/opts/GNURLOPT_CLOSESOCKETDATA.3
+++ b/docs/libcurl/opts/GNURLOPT_CLOSESOCKETDATA.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_CLOSESOCKETFUNCTION.3 b/docs/libcurl/opts/GNURLOPT_CLOSESOCKETFUNCTION.3
index f7d8d45b4..41b0fdd97 100644
--- a/docs/libcurl/opts/GNURLOPT_CLOSESOCKETFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_CLOSESOCKETFUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_CONNECTTIMEOUT.3 b/docs/libcurl/opts/GNURLOPT_CONNECTTIMEOUT.3
index 60ee364f7..ca8d6f00c 100644
--- a/docs/libcurl/opts/GNURLOPT_CONNECTTIMEOUT.3
+++ b/docs/libcurl/opts/GNURLOPT_CONNECTTIMEOUT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -47,7 +47,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* complete connection within 10 seconds */
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L);
diff --git a/docs/libcurl/opts/GNURLOPT_CONNECTTIMEOUT_MS.3 b/docs/libcurl/opts/GNURLOPT_CONNECTTIMEOUT_MS.3
index da836e0c8..d8a0ac58e 100644
--- a/docs/libcurl/opts/GNURLOPT_CONNECTTIMEOUT_MS.3
+++ b/docs/libcurl/opts/GNURLOPT_CONNECTTIMEOUT_MS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -47,7 +47,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* complete connection within 10000 milliseconds */
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, 10000L);
diff --git a/docs/libcurl/opts/GNURLOPT_CONNECT_ONLY.3 b/docs/libcurl/opts/GNURLOPT_CONNECT_ONLY.3
index 6e7962760..9ee9654e2 100644
--- a/docs/libcurl/opts/GNURLOPT_CONNECT_ONLY.3
+++ b/docs/libcurl/opts/GNURLOPT_CONNECT_ONLY.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_CONNECT_TO.3 b/docs/libcurl/opts/GNURLOPT_CONNECT_TO.3
index a54121001..63532347a 100644
--- a/docs/libcurl/opts/GNURLOPT_CONNECT_TO.3
+++ b/docs/libcurl/opts/GNURLOPT_CONNECT_TO.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -93,7 +93,7 @@ connect_to = curl_slist_append(NULL, "example.com::server1.example.com:");
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_CONNECT_TO, connect_to);
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLOPT_CONV_FROM_NETWORK_FUNCTION.3 b/docs/libcurl/opts/GNURLOPT_CONV_FROM_NETWORK_FUNCTION.3
index 783395aec..dd1f32ad7 100644
--- a/docs/libcurl/opts/GNURLOPT_CONV_FROM_NETWORK_FUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_CONV_FROM_NETWORK_FUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_CONV_FROM_UTF8_FUNCTION.3 b/docs/libcurl/opts/GNURLOPT_CONV_FROM_UTF8_FUNCTION.3
index 42c0a976a..64ce846b5 100644
--- a/docs/libcurl/opts/GNURLOPT_CONV_FROM_UTF8_FUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_CONV_FROM_UTF8_FUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_CONV_TO_NETWORK_FUNCTION.3 b/docs/libcurl/opts/GNURLOPT_CONV_TO_NETWORK_FUNCTION.3
index b2a0629b4..5e81d8f41 100644
--- a/docs/libcurl/opts/GNURLOPT_CONV_TO_NETWORK_FUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_CONV_TO_NETWORK_FUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_COOKIE.3 b/docs/libcurl/opts/GNURLOPT_COOKIE.3
index 3a2a1967e..49937b430 100644
--- a/docs/libcurl/opts/GNURLOPT_COOKIE.3
+++ b/docs/libcurl/opts/GNURLOPT_COOKIE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -66,7 +66,7 @@ HTTP
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_setopt(curl, CURLOPT_COOKIE, "tool=curl; fun=yes;");
diff --git a/docs/libcurl/opts/GNURLOPT_COOKIEFILE.3 b/docs/libcurl/opts/GNURLOPT_COOKIEFILE.3
index 50298e550..369037b91 100644
--- a/docs/libcurl/opts/GNURLOPT_COOKIEFILE.3
+++ b/docs/libcurl/opts/GNURLOPT_COOKIEFILE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -65,7 +65,7 @@ HTTP
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
/* get cookies from an existing file */
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/tmp/cookies.txt");
@@ -78,7 +78,7 @@ if(curl) {
.SH "Cookie file format"
The cookie file format and general cookie concepts in curl are described in
the HTTP-COOKIES.md file, also hosted online here:
-https://curl.haxx.se/docs/http-cookies.html
+https://curl.se/docs/http-cookies.html
.SH AVAILABILITY
As long as HTTP is supported
.SH RETURN VALUE
diff --git a/docs/libcurl/opts/GNURLOPT_COOKIEJAR.3 b/docs/libcurl/opts/GNURLOPT_COOKIEJAR.3
index 0a6f60ba0..849a09630 100644
--- a/docs/libcurl/opts/GNURLOPT_COOKIEJAR.3
+++ b/docs/libcurl/opts/GNURLOPT_COOKIEJAR.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -57,7 +57,7 @@ HTTP
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
/* export cookies to this file when closing the handle */
curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "/tmp/cookies.txt");
diff --git a/docs/libcurl/opts/GNURLOPT_COOKIELIST.3 b/docs/libcurl/opts/GNURLOPT_COOKIELIST.3
index fe0c19380..45902351e 100644
--- a/docs/libcurl/opts/GNURLOPT_COOKIELIST.3
+++ b/docs/libcurl/opts/GNURLOPT_COOKIELIST.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -107,7 +107,7 @@ curl_easy_cleanup(curl); /* cookies exported to cookies.txt */
.SH "Cookie file format"
The cookie file format and general cookie concepts in curl are described in
the HTTP-COOKIES.md file, also hosted online here:
-https://curl.haxx.se/docs/http-cookies.html
+https://curl.se/docs/http-cookies.html
.SH AVAILABILITY
ALL was added in 7.14.1
diff --git a/docs/libcurl/opts/GNURLOPT_COOKIESESSION.3 b/docs/libcurl/opts/GNURLOPT_COOKIESESSION.3
index 5911c949d..8725f3691 100644
--- a/docs/libcurl/opts/GNURLOPT_COOKIESESSION.3
+++ b/docs/libcurl/opts/GNURLOPT_COOKIESESSION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -45,7 +45,7 @@ HTTP
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
/* new "session", don't load session cookies */
curl_easy_setopt(curl, CURLOPT_COOKIESESSION, 1L);
diff --git a/docs/libcurl/opts/GNURLOPT_COPYPOSTFIELDS.3 b/docs/libcurl/opts/GNURLOPT_COPYPOSTFIELDS.3
index 9a6940663..057354b44 100644
--- a/docs/libcurl/opts/GNURLOPT_COPYPOSTFIELDS.3
+++ b/docs/libcurl/opts/GNURLOPT_COPYPOSTFIELDS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -50,7 +50,7 @@ HTTP(S)
CURL *curl = curl_easy_init();
if(curl) {
char local_buffer[1024]="data to send";
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* size of the data to copy from the buffer and send in the request */
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 12L);
diff --git a/docs/libcurl/opts/GNURLOPT_CRLF.3 b/docs/libcurl/opts/GNURLOPT_CRLF.3
index 461a295df..1b030b941 100644
--- a/docs/libcurl/opts/GNURLOPT_CRLF.3
+++ b/docs/libcurl/opts/GNURLOPT_CRLF.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_CRLFILE.3 b/docs/libcurl/opts/GNURLOPT_CRLFILE.3
index bffc55b8a..49a56c53e 100644
--- a/docs/libcurl/opts/GNURLOPT_CRLFILE.3
+++ b/docs/libcurl/opts/GNURLOPT_CRLFILE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_CURLU.3 b/docs/libcurl/opts/GNURLOPT_CURLU.3
index 4721ed6ac..f673d003d 100644
--- a/docs/libcurl/opts/GNURLOPT_CURLU.3
+++ b/docs/libcurl/opts/GNURLOPT_CURLU.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -50,7 +50,7 @@ CURLU *urlp = curl_url();
int res = 0;
if(curl) {
- res = curl_url_set(urlp, CURLUPART_URL, "http://example.com", 0);
+ res = curl_url_set(urlp, CURLUPART_URL, "https://example.com", 0);
curl_easy_setopt(handle, CURLOPT_CURLU, urlp);
diff --git a/docs/libcurl/opts/GNURLOPT_CUSTOMREQUEST.3 b/docs/libcurl/opts/GNURLOPT_CUSTOMREQUEST.3
index 1bd5020c5..133ae9286 100644
--- a/docs/libcurl/opts/GNURLOPT_CUSTOMREQUEST.3
+++ b/docs/libcurl/opts/GNURLOPT_CUSTOMREQUEST.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -91,7 +91,7 @@ HTTP, FTP, IMAP, POP3 and SMTP
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
/* DELETE the given path */
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
diff --git a/docs/libcurl/opts/GNURLOPT_DEBUGDATA.3 b/docs/libcurl/opts/GNURLOPT_DEBUGDATA.3
index 1435ee039..a4746f51c 100644
--- a/docs/libcurl/opts/GNURLOPT_DEBUGDATA.3
+++ b/docs/libcurl/opts/GNURLOPT_DEBUGDATA.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -36,7 +36,7 @@ NULL
.SH PROTOCOLS
All
.SH EXAMPLE
-https://curl.haxx.se/libcurl/c/debug.html
+https://curl.se/libcurl/c/debug.html
.SH AVAILABILITY
Always
.SH RETURN VALUE
diff --git a/docs/libcurl/opts/GNURLOPT_DEBUGFUNCTION.3 b/docs/libcurl/opts/GNURLOPT_DEBUGFUNCTION.3
index c470cdac1..c20a9ed8b 100644
--- a/docs/libcurl/opts/GNURLOPT_DEBUGFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_DEBUGFUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -166,7 +166,7 @@ int main(void)
/* example.com is redirected, so we tell libcurl to follow redirection */
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
res = curl_easy_perform(curl);
/* Check for errors */
if(res != CURLE_OK)
diff --git a/docs/libcurl/opts/GNURLOPT_DEFAULT_PROTOCOL.3 b/docs/libcurl/opts/GNURLOPT_DEFAULT_PROTOCOL.3
index 92f4fc253..760b180bf 100644
--- a/docs/libcurl/opts/GNURLOPT_DEFAULT_PROTOCOL.3
+++ b/docs/libcurl/opts/GNURLOPT_DEFAULT_PROTOCOL.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_DIRLISTONLY.3 b/docs/libcurl/opts/GNURLOPT_DIRLISTONLY.3
index 8ecb04fe2..81722df09 100644
--- a/docs/libcurl/opts/GNURLOPT_DIRLISTONLY.3
+++ b/docs/libcurl/opts/GNURLOPT_DIRLISTONLY.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_DISALLOW_USERNAME_IN_URL.3 b/docs/libcurl/opts/GNURLOPT_DISALLOW_USERNAME_IN_URL.3
index a70e95d1a..46e1ffba4 100644
--- a/docs/libcurl/opts/GNURLOPT_DISALLOW_USERNAME_IN_URL.3
+++ b/docs/libcurl/opts/GNURLOPT_DISALLOW_USERNAME_IN_URL.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -39,7 +39,7 @@ Several
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_setopt(curl, CURLOPT_DISALLOW_USERNAME_IN_URL, 1L);
curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLOPT_DNS_CACHE_TIMEOUT.3 b/docs/libcurl/opts/GNURLOPT_DNS_CACHE_TIMEOUT.3
index a05134089..9f41a67dd 100644
--- a/docs/libcurl/opts/GNURLOPT_DNS_CACHE_TIMEOUT.3
+++ b/docs/libcurl/opts/GNURLOPT_DNS_CACHE_TIMEOUT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -50,7 +50,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
/* only reuse addresses for a very short time */
curl_easy_setopt(curl, CURLOPT_DNS_CACHE_TIMEOUT, 2L);
diff --git a/docs/libcurl/opts/GNURLOPT_DNS_INTERFACE.3 b/docs/libcurl/opts/GNURLOPT_DNS_INTERFACE.3
index 9d3426326..5ab359014 100644
--- a/docs/libcurl/opts/GNURLOPT_DNS_INTERFACE.3
+++ b/docs/libcurl/opts/GNURLOPT_DNS_INTERFACE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -42,7 +42,7 @@ NULL
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
curl_easy_setopt(curl, CURLOPT_DNS_INTERFACE, "eth0");
ret = curl_easy_perform(curl);
curl_easy_cleanup(curl);
diff --git a/docs/libcurl/opts/GNURLOPT_DNS_LOCAL_IP4.3 b/docs/libcurl/opts/GNURLOPT_DNS_LOCAL_IP4.3
index df1578f9b..def010fee 100644
--- a/docs/libcurl/opts/GNURLOPT_DNS_LOCAL_IP4.3
+++ b/docs/libcurl/opts/GNURLOPT_DNS_LOCAL_IP4.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -43,7 +43,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
curl_easy_setopt(curl, CURLOPT_DNS_LOCAL_IP4, "192.168.0.14");
ret = curl_easy_perform(curl);
curl_easy_cleanup(curl);
diff --git a/docs/libcurl/opts/GNURLOPT_DNS_LOCAL_IP6.3 b/docs/libcurl/opts/GNURLOPT_DNS_LOCAL_IP6.3
index 3e11d2a68..6bf9d6590 100644
--- a/docs/libcurl/opts/GNURLOPT_DNS_LOCAL_IP6.3
+++ b/docs/libcurl/opts/GNURLOPT_DNS_LOCAL_IP6.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -43,7 +43,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
curl_easy_setopt(curl, CURLOPT_DNS_LOCAL_IP6, "fe80::a9ff:fe46:b619");
ret = curl_easy_perform(curl);
curl_easy_cleanup(curl);
diff --git a/docs/libcurl/opts/GNURLOPT_DNS_SERVERS.3 b/docs/libcurl/opts/GNURLOPT_DNS_SERVERS.3
index 51cc3e7b3..4c21b40fd 100644
--- a/docs/libcurl/opts/GNURLOPT_DNS_SERVERS.3
+++ b/docs/libcurl/opts/GNURLOPT_DNS_SERVERS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -47,7 +47,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
curl_easy_setopt(curl, CURLOPT_DNS_SERVERS, "192.168.1.100:53,192.168.1.101");
ret = curl_easy_perform(curl);
curl_easy_cleanup(curl);
diff --git a/docs/libcurl/opts/GNURLOPT_DNS_SHUFFLE_ADDRESSES.3 b/docs/libcurl/opts/GNURLOPT_DNS_SHUFFLE_ADDRESSES.3
index c8528fe2a..f729ed397 100644
--- a/docs/libcurl/opts/GNURLOPT_DNS_SHUFFLE_ADDRESSES.3
+++ b/docs/libcurl/opts/GNURLOPT_DNS_SHUFFLE_ADDRESSES.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_DNS_USE_GLOBAL_CACHE.3 b/docs/libcurl/opts/GNURLOPT_DNS_USE_GLOBAL_CACHE.3
index 6b81d42cd..25ce68d8e 100644
--- a/docs/libcurl/opts/GNURLOPT_DNS_USE_GLOBAL_CACHE.3
+++ b/docs/libcurl/opts/GNURLOPT_DNS_USE_GLOBAL_CACHE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -29,7 +29,7 @@ CURLOPT_DNS_USE_GLOBAL_CACHE \- enable/disable global DNS cache
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_DNS_USE_GLOBAL_CACHE,
long enable);
.SH DESCRIPTION
-Has no function since 7.62.0. Do note use!
+Has no function since 7.62.0. Do not use!
Pass a long. If the \fIenable\fP value is 1, it tells curl to use a global DNS
cache that will survive between easy handle creations and deletions. This is
diff --git a/docs/libcurl/opts/GNURLOPT_DOH_URL.3 b/docs/libcurl/opts/GNURLOPT_DOH_URL.3
index 2af19959c..ffbddad1c 100644
--- a/docs/libcurl/opts/GNURLOPT_DOH_URL.3
+++ b/docs/libcurl/opts/GNURLOPT_DOH_URL.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -53,7 +53,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_setopt(curl, CURLOPT_DOH_URL, "https://dns.example.com");
curl_easy_perform(curl);
}
diff --git a/docs/libcurl/opts/GNURLOPT_EGDSOCKET.3 b/docs/libcurl/opts/GNURLOPT_EGDSOCKET.3
index 466091c5c..d5cbf870e 100644
--- a/docs/libcurl/opts/GNURLOPT_EGDSOCKET.3
+++ b/docs/libcurl/opts/GNURLOPT_EGDSOCKET.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_ERRORBUFFER.3 b/docs/libcurl/opts/GNURLOPT_ERRORBUFFER.3
index caf21ba21..b8a7523f7 100644
--- a/docs/libcurl/opts/GNURLOPT_ERRORBUFFER.3
+++ b/docs/libcurl/opts/GNURLOPT_ERRORBUFFER.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -56,7 +56,7 @@ if(curl) {
CURLcode res;
char errbuf[CURL_ERROR_SIZE];
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* provide a buffer to store errors in */
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
diff --git a/docs/libcurl/opts/GNURLOPT_EXPECT_100_TIMEOUT_MS.3 b/docs/libcurl/opts/GNURLOPT_EXPECT_100_TIMEOUT_MS.3
index ce0dbcf64..596f44c92 100644
--- a/docs/libcurl/opts/GNURLOPT_EXPECT_100_TIMEOUT_MS.3
+++ b/docs/libcurl/opts/GNURLOPT_EXPECT_100_TIMEOUT_MS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -43,7 +43,7 @@ HTTP
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* wait 3 seconds for 100-continue */
curl_easy_setopt(curl, CURLOPT_EXPECT_100_TIMEOUT_MS, 3000L);
diff --git a/docs/libcurl/opts/GNURLOPT_FAILONERROR.3 b/docs/libcurl/opts/GNURLOPT_FAILONERROR.3
index 2e9662c0e..241f1f37f 100644
--- a/docs/libcurl/opts/GNURLOPT_FAILONERROR.3
+++ b/docs/libcurl/opts/GNURLOPT_FAILONERROR.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_FILETIME.3 b/docs/libcurl/opts/GNURLOPT_FILETIME.3
index fa74147fc..bdb5a1b7f 100644
--- a/docs/libcurl/opts/GNURLOPT_FILETIME.3
+++ b/docs/libcurl/opts/GNURLOPT_FILETIME.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_FNMATCH_DATA.3 b/docs/libcurl/opts/GNURLOPT_FNMATCH_DATA.3
index 37c5db51d..eb1b8bf48 100644
--- a/docs/libcurl/opts/GNURLOPT_FNMATCH_DATA.3
+++ b/docs/libcurl/opts/GNURLOPT_FNMATCH_DATA.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_FNMATCH_FUNCTION.3 b/docs/libcurl/opts/GNURLOPT_FNMATCH_FUNCTION.3
index 1783f8c3f..99f3d0a00 100644
--- a/docs/libcurl/opts/GNURLOPT_FNMATCH_FUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_FNMATCH_FUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_FOLLOWLOCATION.3 b/docs/libcurl/opts/GNURLOPT_FOLLOWLOCATION.3
index bc7d76ae5..0b2f60338 100644
--- a/docs/libcurl/opts/GNURLOPT_FOLLOWLOCATION.3
+++ b/docs/libcurl/opts/GNURLOPT_FOLLOWLOCATION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -63,7 +63,7 @@ HTTP(S)
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* example.com is redirected, so we tell libcurl to follow redirection */
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
diff --git a/docs/libcurl/opts/GNURLOPT_FORBID_REUSE.3 b/docs/libcurl/opts/GNURLOPT_FORBID_REUSE.3
index 6135d29ed..4bc0c2715 100644
--- a/docs/libcurl/opts/GNURLOPT_FORBID_REUSE.3
+++ b/docs/libcurl/opts/GNURLOPT_FORBID_REUSE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_FRESH_CONNECT.3 b/docs/libcurl/opts/GNURLOPT_FRESH_CONNECT.3
index e84d7db8f..5aad37d3f 100644
--- a/docs/libcurl/opts/GNURLOPT_FRESH_CONNECT.3
+++ b/docs/libcurl/opts/GNURLOPT_FRESH_CONNECT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_FTPPORT.3 b/docs/libcurl/opts/GNURLOPT_FTPPORT.3
index e217fcde4..e228d30e0 100644
--- a/docs/libcurl/opts/GNURLOPT_FTPPORT.3
+++ b/docs/libcurl/opts/GNURLOPT_FTPPORT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_FTPSSLAUTH.3 b/docs/libcurl/opts/GNURLOPT_FTPSSLAUTH.3
index ee161143d..f625a714e 100644
--- a/docs/libcurl/opts/GNURLOPT_FTPSSLAUTH.3
+++ b/docs/libcurl/opts/GNURLOPT_FTPSSLAUTH.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_FTP_ACCOUNT.3 b/docs/libcurl/opts/GNURLOPT_FTP_ACCOUNT.3
index d3b16a6ef..b05577ea0 100644
--- a/docs/libcurl/opts/GNURLOPT_FTP_ACCOUNT.3
+++ b/docs/libcurl/opts/GNURLOPT_FTP_ACCOUNT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_FTP_ALTERNATIVE_TO_USER.3 b/docs/libcurl/opts/GNURLOPT_FTP_ALTERNATIVE_TO_USER.3
index b3f1addac..cef286aa0 100644
--- a/docs/libcurl/opts/GNURLOPT_FTP_ALTERNATIVE_TO_USER.3
+++ b/docs/libcurl/opts/GNURLOPT_FTP_ALTERNATIVE_TO_USER.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_FTP_CREATE_MISSING_DIRS.3 b/docs/libcurl/opts/GNURLOPT_FTP_CREATE_MISSING_DIRS.3
index a112447f9..7215affd6 100644
--- a/docs/libcurl/opts/GNURLOPT_FTP_CREATE_MISSING_DIRS.3
+++ b/docs/libcurl/opts/GNURLOPT_FTP_CREATE_MISSING_DIRS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_FTP_FILEMETHOD.3 b/docs/libcurl/opts/GNURLOPT_FTP_FILEMETHOD.3
index 9c616e629..7df3fa9a6 100644
--- a/docs/libcurl/opts/GNURLOPT_FTP_FILEMETHOD.3
+++ b/docs/libcurl/opts/GNURLOPT_FTP_FILEMETHOD.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_FTP_RESPONSE_TIMEOUT.3 b/docs/libcurl/opts/GNURLOPT_FTP_RESPONSE_TIMEOUT.3
index b87e0b522..1ded77eb1 100644
--- a/docs/libcurl/opts/GNURLOPT_FTP_RESPONSE_TIMEOUT.3
+++ b/docs/libcurl/opts/GNURLOPT_FTP_RESPONSE_TIMEOUT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_FTP_SKIP_PASV_IP.3 b/docs/libcurl/opts/GNURLOPT_FTP_SKIP_PASV_IP.3
index a8b8eeeef..08307d9d6 100644
--- a/docs/libcurl/opts/GNURLOPT_FTP_SKIP_PASV_IP.3
+++ b/docs/libcurl/opts/GNURLOPT_FTP_SKIP_PASV_IP.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -35,11 +35,13 @@ address it already uses for the control connection. But it will use the port
number from the 227-response.
This option thus allows libcurl to work around broken server installations
-that due to NATs, firewalls or incompetence report the wrong IP address back.
+that due to NATs, firewalls or incompetence report the wrong IP address
+back. Setting the option also reduces the risk for various sorts of client
+abuse by malicious servers.
This option has no effect if PORT, EPRT or EPSV is used instead of PASV.
.SH DEFAULT
-0
+1 since 7.74.0, was 0 before then.
.SH PROTOCOLS
FTP
.SH EXAMPLE
diff --git a/docs/libcurl/opts/GNURLOPT_FTP_SSL_CCC.3 b/docs/libcurl/opts/GNURLOPT_FTP_SSL_CCC.3
index d1d243c18..d88abdf60 100644
--- a/docs/libcurl/opts/GNURLOPT_FTP_SSL_CCC.3
+++ b/docs/libcurl/opts/GNURLOPT_FTP_SSL_CCC.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_FTP_USE_EPRT.3 b/docs/libcurl/opts/GNURLOPT_FTP_USE_EPRT.3
index 9c6cd6365..7b3f6cfde 100644
--- a/docs/libcurl/opts/GNURLOPT_FTP_USE_EPRT.3
+++ b/docs/libcurl/opts/GNURLOPT_FTP_USE_EPRT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_FTP_USE_EPSV.3 b/docs/libcurl/opts/GNURLOPT_FTP_USE_EPSV.3
index 7bcdb6649..ff8e9620a 100644
--- a/docs/libcurl/opts/GNURLOPT_FTP_USE_EPSV.3
+++ b/docs/libcurl/opts/GNURLOPT_FTP_USE_EPSV.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_FTP_USE_PRET.3 b/docs/libcurl/opts/GNURLOPT_FTP_USE_PRET.3
index ded3b1f70..b7b38c8c5 100644
--- a/docs/libcurl/opts/GNURLOPT_FTP_USE_PRET.3
+++ b/docs/libcurl/opts/GNURLOPT_FTP_USE_PRET.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_GSSAPI_DELEGATION.3 b/docs/libcurl/opts/GNURLOPT_GSSAPI_DELEGATION.3
index 2ee67395d..91d16bacb 100644
--- a/docs/libcurl/opts/GNURLOPT_GSSAPI_DELEGATION.3
+++ b/docs/libcurl/opts/GNURLOPT_GSSAPI_DELEGATION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 b/docs/libcurl/opts/GNURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3
index 9c8ed42f1..d6ee0cb57 100644
--- a/docs/libcurl/opts/GNURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3
+++ b/docs/libcurl/opts/GNURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_HAPROXYPROTOCOL.3 b/docs/libcurl/opts/GNURLOPT_HAPROXYPROTOCOL.3
index 4d15b6479..4b9d7ebb5 100644
--- a/docs/libcurl/opts/GNURLOPT_HAPROXYPROTOCOL.3
+++ b/docs/libcurl/opts/GNURLOPT_HAPROXYPROTOCOL.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_HEADER.3 b/docs/libcurl/opts/GNURLOPT_HEADER.3
index 325014871..3cb7df200 100644
--- a/docs/libcurl/opts/GNURLOPT_HEADER.3
+++ b/docs/libcurl/opts/GNURLOPT_HEADER.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -55,7 +55,7 @@ Most
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_setopt(curl, CURLOPT_HEADER, 1L);
diff --git a/docs/libcurl/opts/GNURLOPT_HEADERDATA.3 b/docs/libcurl/opts/GNURLOPT_HEADERDATA.3
index 84c573498..fadf8c190 100644
--- a/docs/libcurl/opts/GNURLOPT_HEADERDATA.3
+++ b/docs/libcurl/opts/GNURLOPT_HEADERDATA.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -60,7 +60,7 @@ static size_t header_callback(char *buffer, size_t size,
CURL *curl = curl_easy_init();
if(curl) {
struct my_info my = { 10, "the cookies are in the cupboard" };
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback);
diff --git a/docs/libcurl/opts/GNURLOPT_HEADERFUNCTION.3 b/docs/libcurl/opts/GNURLOPT_HEADERFUNCTION.3
index c62390b5d..bbd8a731e 100644
--- a/docs/libcurl/opts/GNURLOPT_HEADERFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_HEADERFUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -102,7 +102,7 @@ static size_t header_callback(char *buffer, size_t size,
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback);
diff --git a/docs/libcurl/opts/GNURLOPT_HEADEROPT.3 b/docs/libcurl/opts/GNURLOPT_HEADEROPT.3
index 1171657fd..16d6521b3 100644
--- a/docs/libcurl/opts/GNURLOPT_HEADEROPT.3
+++ b/docs/libcurl/opts/GNURLOPT_HEADEROPT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_HTTP09_ALLOWED.3 b/docs/libcurl/opts/GNURLOPT_HTTP09_ALLOWED.3
index 8856c1a19..45c4e38c9 100644
--- a/docs/libcurl/opts/GNURLOPT_HTTP09_ALLOWED.3
+++ b/docs/libcurl/opts/GNURLOPT_HTTP09_ALLOWED.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_HTTP200ALIASES.3 b/docs/libcurl/opts/GNURLOPT_HTTP200ALIASES.3
index b0edad006..4de2797b2 100644
--- a/docs/libcurl/opts/GNURLOPT_HTTP200ALIASES.3
+++ b/docs/libcurl/opts/GNURLOPT_HTTP200ALIASES.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -53,7 +53,7 @@ HTTP
CURL *curl = curl_easy_init();
if(curl) {
struct curl_slist *list;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
list = curl_slist_append(NULL, "ICY 200 OK");
list = curl_slist_append(list, "WEIRDO 99 FINE");
diff --git a/docs/libcurl/opts/GNURLOPT_HTTPAUTH.3 b/docs/libcurl/opts/GNURLOPT_HTTPAUTH.3
index 13b7c1f52..3c5b06d8c 100644
--- a/docs/libcurl/opts/GNURLOPT_HTTPAUTH.3
+++ b/docs/libcurl/opts/GNURLOPT_HTTPAUTH.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_HTTPGET.3 b/docs/libcurl/opts/GNURLOPT_HTTPGET.3
index cb2006640..60146e448 100644
--- a/docs/libcurl/opts/GNURLOPT_HTTPGET.3
+++ b/docs/libcurl/opts/GNURLOPT_HTTPGET.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -46,7 +46,7 @@ HTTP(S)
.nf
curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* use a GET to fetch this */
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
diff --git a/docs/libcurl/opts/GNURLOPT_HTTPHEADER.3 b/docs/libcurl/opts/GNURLOPT_HTTPHEADER.3
index 017cb0a37..02a87fbb4 100644
--- a/docs/libcurl/opts/GNURLOPT_HTTPHEADER.3
+++ b/docs/libcurl/opts/GNURLOPT_HTTPHEADER.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -102,7 +102,7 @@ CURL *curl = curl_easy_init();
struct curl_slist *list = NULL;
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
list = curl_slist_append(list, "Shoesize: 10");
list = curl_slist_append(list, "Accept:");
diff --git a/docs/libcurl/opts/GNURLOPT_HTTPPOST.3 b/docs/libcurl/opts/GNURLOPT_HTTPPOST.3
index 7001c7f0a..0a0f8f064 100644
--- a/docs/libcurl/opts/GNURLOPT_HTTPPOST.3
+++ b/docs/libcurl/opts/GNURLOPT_HTTPPOST.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_HTTPPROXYTUNNEL.3 b/docs/libcurl/opts/GNURLOPT_HTTPPROXYTUNNEL.3
index d4975406f..da5a18beb 100644
--- a/docs/libcurl/opts/GNURLOPT_HTTPPROXYTUNNEL.3
+++ b/docs/libcurl/opts/GNURLOPT_HTTPPROXYTUNNEL.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_HTTP_CONTENT_DECODING.3 b/docs/libcurl/opts/GNURLOPT_HTTP_CONTENT_DECODING.3
index 6a3f64779..386227140 100644
--- a/docs/libcurl/opts/GNURLOPT_HTTP_CONTENT_DECODING.3
+++ b/docs/libcurl/opts/GNURLOPT_HTTP_CONTENT_DECODING.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_HTTP_TRANSFER_DECODING.3 b/docs/libcurl/opts/GNURLOPT_HTTP_TRANSFER_DECODING.3
index 0ce86fd68..0983ecef4 100644
--- a/docs/libcurl/opts/GNURLOPT_HTTP_TRANSFER_DECODING.3
+++ b/docs/libcurl/opts/GNURLOPT_HTTP_TRANSFER_DECODING.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_HTTP_VERSION.3 b/docs/libcurl/opts/GNURLOPT_HTTP_VERSION.3
index 2782e69a2..38657f6ae 100644
--- a/docs/libcurl/opts/GNURLOPT_HTTP_VERSION.3
+++ b/docs/libcurl/opts/GNURLOPT_HTTP_VERSION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_IGNORE_CONTENT_LENGTH.3 b/docs/libcurl/opts/GNURLOPT_IGNORE_CONTENT_LENGTH.3
index bee16681c..97d668684 100644
--- a/docs/libcurl/opts/GNURLOPT_IGNORE_CONTENT_LENGTH.3
+++ b/docs/libcurl/opts/GNURLOPT_IGNORE_CONTENT_LENGTH.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -51,7 +51,7 @@ HTTP
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* we know the server is silly, ignore content-length */
curl_easy_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, 1L);
diff --git a/docs/libcurl/opts/GNURLOPT_INFILESIZE.3 b/docs/libcurl/opts/GNURLOPT_INFILESIZE.3
index 197f9cd46..e01995237 100644
--- a/docs/libcurl/opts/GNURLOPT_INFILESIZE.3
+++ b/docs/libcurl/opts/GNURLOPT_INFILESIZE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_INFILESIZE_LARGE.3 b/docs/libcurl/opts/GNURLOPT_INFILESIZE_LARGE.3
index 8a5acfc04..d05592e93 100644
--- a/docs/libcurl/opts/GNURLOPT_INFILESIZE_LARGE.3
+++ b/docs/libcurl/opts/GNURLOPT_INFILESIZE_LARGE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_INTERFACE.3 b/docs/libcurl/opts/GNURLOPT_INTERFACE.3
index e93351360..ba6cfca36 100644
--- a/docs/libcurl/opts/GNURLOPT_INTERFACE.3
+++ b/docs/libcurl/opts/GNURLOPT_INTERFACE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -54,7 +54,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
curl_easy_setopt(curl, CURLOPT_INTERFACE, "eth0");
diff --git a/docs/libcurl/opts/GNURLOPT_INTERLEAVEDATA.3 b/docs/libcurl/opts/GNURLOPT_INTERLEAVEDATA.3
index 20fedbebd..53d151136 100644
--- a/docs/libcurl/opts/GNURLOPT_INTERLEAVEDATA.3
+++ b/docs/libcurl/opts/GNURLOPT_INTERLEAVEDATA.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_INTERLEAVEFUNCTION.3 b/docs/libcurl/opts/GNURLOPT_INTERLEAVEFUNCTION.3
index c2c267e7f..b3e5f292c 100644
--- a/docs/libcurl/opts/GNURLOPT_INTERLEAVEFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_INTERLEAVEFUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_IOCTLDATA.3 b/docs/libcurl/opts/GNURLOPT_IOCTLDATA.3
index e450d86b5..10778affb 100644
--- a/docs/libcurl/opts/GNURLOPT_IOCTLDATA.3
+++ b/docs/libcurl/opts/GNURLOPT_IOCTLDATA.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_IOCTLFUNCTION.3 b/docs/libcurl/opts/GNURLOPT_IOCTLFUNCTION.3
index f37f9c036..99bfd489a 100644
--- a/docs/libcurl/opts/GNURLOPT_IOCTLFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_IOCTLFUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_IPRESOLVE.3 b/docs/libcurl/opts/GNURLOPT_IPRESOLVE.3
index fe7a0f90d..ef040ff71 100644
--- a/docs/libcurl/opts/GNURLOPT_IPRESOLVE.3
+++ b/docs/libcurl/opts/GNURLOPT_IPRESOLVE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -45,7 +45,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
/* resolve host name using IPv6-names only */
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6);
diff --git a/docs/libcurl/opts/GNURLOPT_ISSUERCERT.3 b/docs/libcurl/opts/GNURLOPT_ISSUERCERT.3
index 30f0c756a..70ed96ef8 100644
--- a/docs/libcurl/opts/GNURLOPT_ISSUERCERT.3
+++ b/docs/libcurl/opts/GNURLOPT_ISSUERCERT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_ISSUERCERT_BLOB.3 b/docs/libcurl/opts/GNURLOPT_ISSUERCERT_BLOB.3
index 0495b6f67..e97204af9 100644
--- a/docs/libcurl/opts/GNURLOPT_ISSUERCERT_BLOB.3
+++ b/docs/libcurl/opts/GNURLOPT_ISSUERCERT_BLOB.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_KEEP_SENDING_ON_ERROR.3 b/docs/libcurl/opts/GNURLOPT_KEEP_SENDING_ON_ERROR.3
index ec53000d4..9bea3d920 100644
--- a/docs/libcurl/opts/GNURLOPT_KEEP_SENDING_ON_ERROR.3
+++ b/docs/libcurl/opts/GNURLOPT_KEEP_SENDING_ON_ERROR.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_KEYPASSWD.3 b/docs/libcurl/opts/GNURLOPT_KEYPASSWD.3
index 9145b0554..c54769064 100644
--- a/docs/libcurl/opts/GNURLOPT_KEYPASSWD.3
+++ b/docs/libcurl/opts/GNURLOPT_KEYPASSWD.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -43,7 +43,7 @@ All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc.
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
curl_easy_setopt(curl, CURLOPT_SSLCERT, "client.pem");
curl_easy_setopt(curl, CURLOPT_SSLKEY, "key.pem");
curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "superman");
diff --git a/docs/libcurl/opts/GNURLOPT_KRBLEVEL.3 b/docs/libcurl/opts/GNURLOPT_KRBLEVEL.3
index 6735a09d1..0ff2ff6e5 100644
--- a/docs/libcurl/opts/GNURLOPT_KRBLEVEL.3
+++ b/docs/libcurl/opts/GNURLOPT_KRBLEVEL.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_LOCALPORT.3 b/docs/libcurl/opts/GNURLOPT_LOCALPORT.3
index 3376873e8..ca76bdfeb 100644
--- a/docs/libcurl/opts/GNURLOPT_LOCALPORT.3
+++ b/docs/libcurl/opts/GNURLOPT_LOCALPORT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -40,7 +40,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
curl_easy_setopt(curl, CURLOPT_LOCALPORT, 49152L);
/* and try 20 more ports following that */
curl_easy_setopt(curl, CURLOPT_LOCALPORTRANGE, 20L);
diff --git a/docs/libcurl/opts/GNURLOPT_LOCALPORTRANGE.3 b/docs/libcurl/opts/GNURLOPT_LOCALPORTRANGE.3
index 20aa156ad..f4a2c13e8 100644
--- a/docs/libcurl/opts/GNURLOPT_LOCALPORTRANGE.3
+++ b/docs/libcurl/opts/GNURLOPT_LOCALPORTRANGE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -44,7 +44,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
curl_easy_setopt(curl, CURLOPT_LOCALPORT, 49152L);
/* and try 20 more ports following that */
curl_easy_setopt(curl, CURLOPT_LOCALPORTRANGE, 20L);
diff --git a/docs/libcurl/opts/GNURLOPT_LOGIN_OPTIONS.3 b/docs/libcurl/opts/GNURLOPT_LOGIN_OPTIONS.3
index 5a41a00c1..c65131592 100644
--- a/docs/libcurl/opts/GNURLOPT_LOGIN_OPTIONS.3
+++ b/docs/libcurl/opts/GNURLOPT_LOGIN_OPTIONS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_LOW_SPEED_LIMIT.3 b/docs/libcurl/opts/GNURLOPT_LOW_SPEED_LIMIT.3
index 4f26e6656..05512cff3 100644
--- a/docs/libcurl/opts/GNURLOPT_LOW_SPEED_LIMIT.3
+++ b/docs/libcurl/opts/GNURLOPT_LOW_SPEED_LIMIT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_LOW_SPEED_TIME.3 b/docs/libcurl/opts/GNURLOPT_LOW_SPEED_TIME.3
index 2cfa9d210..9c5b4c121 100644
--- a/docs/libcurl/opts/GNURLOPT_LOW_SPEED_TIME.3
+++ b/docs/libcurl/opts/GNURLOPT_LOW_SPEED_TIME.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_MAIL_AUTH.3 b/docs/libcurl/opts/GNURLOPT_MAIL_AUTH.3
index cebafbcec..670e59e8d 100644
--- a/docs/libcurl/opts/GNURLOPT_MAIL_AUTH.3
+++ b/docs/libcurl/opts/GNURLOPT_MAIL_AUTH.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_MAIL_FROM.3 b/docs/libcurl/opts/GNURLOPT_MAIL_FROM.3
index c2d0d2851..eeac1c0b4 100644
--- a/docs/libcurl/opts/GNURLOPT_MAIL_FROM.3
+++ b/docs/libcurl/opts/GNURLOPT_MAIL_FROM.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_MAIL_RCPT.3 b/docs/libcurl/opts/GNURLOPT_MAIL_RCPT.3
index af43f235c..858947164 100644
--- a/docs/libcurl/opts/GNURLOPT_MAIL_RCPT.3
+++ b/docs/libcurl/opts/GNURLOPT_MAIL_RCPT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_MAIL_RCPT_ALLLOWFAILS.3 b/docs/libcurl/opts/GNURLOPT_MAIL_RCPT_ALLLOWFAILS.3
index d2fdada77..c3b206cb3 100644
--- a/docs/libcurl/opts/GNURLOPT_MAIL_RCPT_ALLLOWFAILS.3
+++ b/docs/libcurl/opts/GNURLOPT_MAIL_RCPT_ALLLOWFAILS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_MAXAGE_CONN.3 b/docs/libcurl/opts/GNURLOPT_MAXAGE_CONN.3
index 61d687b56..17577250a 100644
--- a/docs/libcurl/opts/GNURLOPT_MAXAGE_CONN.3
+++ b/docs/libcurl/opts/GNURLOPT_MAXAGE_CONN.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -48,7 +48,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* only allow 30 seconds idle time */
curl_easy_setopt(curl, CURLOPT_MAXAGE_CONN, 30L);
diff --git a/docs/libcurl/opts/GNURLOPT_MAXCONNECTS.3 b/docs/libcurl/opts/GNURLOPT_MAXCONNECTS.3
index 44efd5143..ba70c481d 100644
--- a/docs/libcurl/opts/GNURLOPT_MAXCONNECTS.3
+++ b/docs/libcurl/opts/GNURLOPT_MAXCONNECTS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_MAXFILESIZE.3 b/docs/libcurl/opts/GNURLOPT_MAXFILESIZE.3
index 6624ad6a6..daad41a75 100644
--- a/docs/libcurl/opts/GNURLOPT_MAXFILESIZE.3
+++ b/docs/libcurl/opts/GNURLOPT_MAXFILESIZE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_MAXFILESIZE_LARGE.3 b/docs/libcurl/opts/GNURLOPT_MAXFILESIZE_LARGE.3
index 2ca01851f..0d958d247 100644
--- a/docs/libcurl/opts/GNURLOPT_MAXFILESIZE_LARGE.3
+++ b/docs/libcurl/opts/GNURLOPT_MAXFILESIZE_LARGE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_MAXREDIRS.3 b/docs/libcurl/opts/GNURLOPT_MAXREDIRS.3
index 159bf7b71..b9f11e0fc 100644
--- a/docs/libcurl/opts/GNURLOPT_MAXREDIRS.3
+++ b/docs/libcurl/opts/GNURLOPT_MAXREDIRS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -44,7 +44,7 @@ HTTP(S)
.nf
curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
/* enable redirect following */
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
diff --git a/docs/libcurl/opts/GNURLOPT_MAX_RECV_SPEED_LARGE.3 b/docs/libcurl/opts/GNURLOPT_MAX_RECV_SPEED_LARGE.3
index 3aa78a890..3f5ef76c6 100644
--- a/docs/libcurl/opts/GNURLOPT_MAX_RECV_SPEED_LARGE.3
+++ b/docs/libcurl/opts/GNURLOPT_MAX_RECV_SPEED_LARGE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_MAX_SEND_SPEED_LARGE.3 b/docs/libcurl/opts/GNURLOPT_MAX_SEND_SPEED_LARGE.3
index cbdcb52c0..e155a49c0 100644
--- a/docs/libcurl/opts/GNURLOPT_MAX_SEND_SPEED_LARGE.3
+++ b/docs/libcurl/opts/GNURLOPT_MAX_SEND_SPEED_LARGE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_MIMEPOST.3 b/docs/libcurl/opts/GNURLOPT_MIMEPOST.3
index 9a71961d3..351b98573 100644
--- a/docs/libcurl/opts/GNURLOPT_MIMEPOST.3
+++ b/docs/libcurl/opts/GNURLOPT_MIMEPOST.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -46,7 +46,7 @@ Since 7.56.0.
This will return CURLE_OK.
.SH EXAMPLE
Using this option implies the use of several mime structure building
-functions: see https://curl.haxx.se/libcurl/c/smtp-mime.html for a complete
+functions: see https://curl.se/libcurl/c/smtp-mime.html for a complete
example.
.SH "SEE ALSO"
.BR curl_mime_init "(3)"
diff --git a/docs/libcurl/opts/GNURLOPT_NETRC.3 b/docs/libcurl/opts/GNURLOPT_NETRC.3
index 67b1772bf..c154458d5 100644
--- a/docs/libcurl/opts/GNURLOPT_NETRC.3
+++ b/docs/libcurl/opts/GNURLOPT_NETRC.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_NETRC_FILE.3 b/docs/libcurl/opts/GNURLOPT_NETRC_FILE.3
index d2a89da87..16a5ab9c4 100644
--- a/docs/libcurl/opts/GNURLOPT_NETRC_FILE.3
+++ b/docs/libcurl/opts/GNURLOPT_NETRC_FILE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_NEW_DIRECTORY_PERMS.3 b/docs/libcurl/opts/GNURLOPT_NEW_DIRECTORY_PERMS.3
index 70512839a..a0f5be21b 100644
--- a/docs/libcurl/opts/GNURLOPT_NEW_DIRECTORY_PERMS.3
+++ b/docs/libcurl/opts/GNURLOPT_NEW_DIRECTORY_PERMS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_NEW_FILE_PERMS.3 b/docs/libcurl/opts/GNURLOPT_NEW_FILE_PERMS.3
index 69af0a378..5af010957 100644
--- a/docs/libcurl/opts/GNURLOPT_NEW_FILE_PERMS.3
+++ b/docs/libcurl/opts/GNURLOPT_NEW_FILE_PERMS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_NOBODY.3 b/docs/libcurl/opts/GNURLOPT_NOBODY.3
index 7a0060e87..d44ff6620 100644
--- a/docs/libcurl/opts/GNURLOPT_NOBODY.3
+++ b/docs/libcurl/opts/GNURLOPT_NOBODY.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -36,7 +36,7 @@ to transfer the body data.
For HTTP operations when \fICURLOPT_NOBODY(3)\fP has been set, unsetting the
option (with 0) will make it a GET again - only if the method is still set to
be HEAD. The proper way to get back to a GET request is to set
-\fICURLOPT_HTTPGET(3)\fP and for other methods, use the POST ur UPLOAD
+\fICURLOPT_HTTPGET(3)\fP and for other methods, use the POST or UPLOAD
options.
Enabling \fICURLOPT_NOBODY(3)\fP means asking for a download without a body.
diff --git a/docs/libcurl/opts/GNURLOPT_NOPROGRESS.3 b/docs/libcurl/opts/GNURLOPT_NOPROGRESS.3
index 4f0635677..da733d4d5 100644
--- a/docs/libcurl/opts/GNURLOPT_NOPROGRESS.3
+++ b/docs/libcurl/opts/GNURLOPT_NOPROGRESS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -40,7 +40,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* enable progress meter */
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
diff --git a/docs/libcurl/opts/GNURLOPT_NOPROXY.3 b/docs/libcurl/opts/GNURLOPT_NOPROXY.3
index bf46a839b..fe0c78d61 100644
--- a/docs/libcurl/opts/GNURLOPT_NOPROXY.3
+++ b/docs/libcurl/opts/GNURLOPT_NOPROXY.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -49,6 +49,10 @@ brackets:
"example.com,::1,localhost"
+IPv6 numerical addresses are compared as strings, so they will only match if
+the representations are the same: "::1" is the same as "::0:1" but they don't
+match.
+
The application does not have to keep the string around after setting this
option.
.SH "Environment variables"
diff --git a/docs/libcurl/opts/GNURLOPT_NOSIGNAL.3 b/docs/libcurl/opts/GNURLOPT_NOSIGNAL.3
index 8a38d8f34..b9b66b1aa 100644
--- a/docs/libcurl/opts/GNURLOPT_NOSIGNAL.3
+++ b/docs/libcurl/opts/GNURLOPT_NOSIGNAL.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_OPENSOCKETDATA.3 b/docs/libcurl/opts/GNURLOPT_OPENSOCKETDATA.3
index be3bf94b9..e8d66c9de 100644
--- a/docs/libcurl/opts/GNURLOPT_OPENSOCKETDATA.3
+++ b/docs/libcurl/opts/GNURLOPT_OPENSOCKETDATA.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_OPENSOCKETFUNCTION.3 b/docs/libcurl/opts/GNURLOPT_OPENSOCKETFUNCTION.3
index 32e75b79b..48b4ea002 100644
--- a/docs/libcurl/opts/GNURLOPT_OPENSOCKETFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_OPENSOCKETFUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PASSWORD.3 b/docs/libcurl/opts/GNURLOPT_PASSWORD.3
index 928903f0a..e9e1045e2 100644
--- a/docs/libcurl/opts/GNURLOPT_PASSWORD.3
+++ b/docs/libcurl/opts/GNURLOPT_PASSWORD.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -44,7 +44,7 @@ Most
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
curl_easy_setopt(curl, CURLOPT_PASSWORD, "qwerty");
diff --git a/docs/libcurl/opts/GNURLOPT_PATH_AS_IS.3 b/docs/libcurl/opts/GNURLOPT_PATH_AS_IS.3
index eb03d0ed1..09051f81b 100644
--- a/docs/libcurl/opts/GNURLOPT_PATH_AS_IS.3
+++ b/docs/libcurl/opts/GNURLOPT_PATH_AS_IS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -48,7 +48,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/../../etc/password");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/../../etc/password");
curl_easy_setopt(curl, CURLOPT_PATH_AS_IS, 1L);
diff --git a/docs/libcurl/opts/GNURLOPT_PINNEDPUBLICKEY.3 b/docs/libcurl/opts/GNURLOPT_PINNEDPUBLICKEY.3
index da2d3b581..bec202d1f 100644
--- a/docs/libcurl/opts/GNURLOPT_PINNEDPUBLICKEY.3
+++ b/docs/libcurl/opts/GNURLOPT_PINNEDPUBLICKEY.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PIPEWAIT.3 b/docs/libcurl/opts/GNURLOPT_PIPEWAIT.3
index 5d68c99c7..4eeece977 100644
--- a/docs/libcurl/opts/GNURLOPT_PIPEWAIT.3
+++ b/docs/libcurl/opts/GNURLOPT_PIPEWAIT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PORT.3 b/docs/libcurl/opts/GNURLOPT_PORT.3
index 978d21d1f..836fdafb0 100644
--- a/docs/libcurl/opts/GNURLOPT_PORT.3
+++ b/docs/libcurl/opts/GNURLOPT_PORT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -45,7 +45,7 @@ Used for all protocols that speak to a port number.
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
curl_easy_setopt(curl, CURLOPT_PORT, 8080L);
ret = curl_easy_perform(curl);
curl_easy_cleanup(curl);
diff --git a/docs/libcurl/opts/GNURLOPT_POST.3 b/docs/libcurl/opts/GNURLOPT_POST.3
index 0b3080e0d..39f70d2eb 100644
--- a/docs/libcurl/opts/GNURLOPT_POST.3
+++ b/docs/libcurl/opts/GNURLOPT_POST.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -72,7 +72,7 @@ HTTP
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
curl_easy_setopt(curl, CURLOPT_POST, 1L);
/* set up the read callback with CURLOPT_READFUNCTION */
diff --git a/docs/libcurl/opts/GNURLOPT_POSTFIELDS.3 b/docs/libcurl/opts/GNURLOPT_POSTFIELDS.3
index 88b16a302..d6b36c8ec 100644
--- a/docs/libcurl/opts/GNURLOPT_POSTFIELDS.3
+++ b/docs/libcurl/opts/GNURLOPT_POSTFIELDS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -69,7 +69,7 @@ CURL *curl = curl_easy_init();
if(curl) {
const char *data = "data to send";
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* size of the POST data */
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 12L);
diff --git a/docs/libcurl/opts/GNURLOPT_POSTFIELDSIZE.3 b/docs/libcurl/opts/GNURLOPT_POSTFIELDSIZE.3
index c3603e00e..37a3bf419 100644
--- a/docs/libcurl/opts/GNURLOPT_POSTFIELDSIZE.3
+++ b/docs/libcurl/opts/GNURLOPT_POSTFIELDSIZE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -44,7 +44,7 @@ CURL *curl = curl_easy_init();
if(curl) {
const char *data = "data to send";
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* size of the POST data */
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long) strlen(data));
diff --git a/docs/libcurl/opts/GNURLOPT_POSTFIELDSIZE_LARGE.3 b/docs/libcurl/opts/GNURLOPT_POSTFIELDSIZE_LARGE.3
index 8d4750a20..3e7c86010 100644
--- a/docs/libcurl/opts/GNURLOPT_POSTFIELDSIZE_LARGE.3
+++ b/docs/libcurl/opts/GNURLOPT_POSTFIELDSIZE_LARGE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -45,7 +45,7 @@ if(curl) {
const char *data = large_chunk;
curl_off_t length_of_data; /* set somehow */
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* size of the POST data */
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, length_of_data);
diff --git a/docs/libcurl/opts/GNURLOPT_POSTQUOTE.3 b/docs/libcurl/opts/GNURLOPT_POSTQUOTE.3
index 1e82453be..ea914dec3 100644
--- a/docs/libcurl/opts/GNURLOPT_POSTQUOTE.3
+++ b/docs/libcurl/opts/GNURLOPT_POSTQUOTE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_POSTREDIR.3 b/docs/libcurl/opts/GNURLOPT_POSTREDIR.3
index 1729c843f..c4da6bd8d 100644
--- a/docs/libcurl/opts/GNURLOPT_POSTREDIR.3
+++ b/docs/libcurl/opts/GNURLOPT_POSTREDIR.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -52,7 +52,7 @@ HTTP(S)
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* a silly POST example */
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "data=true");
diff --git a/docs/libcurl/opts/GNURLOPT_PREQUOTE.3 b/docs/libcurl/opts/GNURLOPT_PREQUOTE.3
index 16d3cc0b6..1ec5510ee 100644
--- a/docs/libcurl/opts/GNURLOPT_PREQUOTE.3
+++ b/docs/libcurl/opts/GNURLOPT_PREQUOTE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PRE_PROXY.3 b/docs/libcurl/opts/GNURLOPT_PRE_PROXY.3
index 28a3b2be7..c66df04a4 100644
--- a/docs/libcurl/opts/GNURLOPT_PRE_PROXY.3
+++ b/docs/libcurl/opts/GNURLOPT_PRE_PROXY.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -64,7 +64,7 @@ All except file://. Note that some protocols don't do very well over proxy.
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/file.txt");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/file.txt");
curl_easy_setopt(curl, CURLOPT_PREPROXY, "socks4://socks-proxy:1080");
curl_easy_setopt(curl, CURLOPT_PROXY, "http://proxy:80");
curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLOPT_PRIVATE.3 b/docs/libcurl/opts/GNURLOPT_PRIVATE.3
index 7074cb8a1..29c5dffb7 100644
--- a/docs/libcurl/opts/GNURLOPT_PRIVATE.3
+++ b/docs/libcurl/opts/GNURLOPT_PRIVATE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -42,7 +42,7 @@ CURL *curl = curl_easy_init();
struct private secrets;
if(curl) {
struct private *extracted;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* store a pointer to our private struct */
curl_easy_setopt(curl, CURLOPT_PRIVATE, &secrets);
diff --git a/docs/libcurl/opts/GNURLOPT_PROGRESSDATA.3 b/docs/libcurl/opts/GNURLOPT_PROGRESSDATA.3
index 8156eaa38..28c228bc6 100644
--- a/docs/libcurl/opts/GNURLOPT_PROGRESSDATA.3
+++ b/docs/libcurl/opts/GNURLOPT_PROGRESSDATA.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -35,7 +35,7 @@ The default value of this parameter is NULL.
.SH PROTOCOLS
All
.SH EXAMPLE
-https://curl.haxx.se/libcurl/c/progressfunc.html
+https://curl.se/libcurl/c/progressfunc.html
.SH AVAILABILITY
Always
.SH RETURN VALUE
diff --git a/docs/libcurl/opts/GNURLOPT_PROGRESSFUNCTION.3 b/docs/libcurl/opts/GNURLOPT_PROGRESSFUNCTION.3
index bfa566ec6..a6151f1fa 100644
--- a/docs/libcurl/opts/GNURLOPT_PROGRESSFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_PROGRESSFUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -78,7 +78,7 @@ users.
.SH PROTOCOLS
All
.SH EXAMPLE
-https://curl.haxx.se/libcurl/c/progressfunc.html
+https://curl.se/libcurl/c/progressfunc.html
.SH AVAILABILITY
Always
.SH RETURN VALUE
diff --git a/docs/libcurl/opts/GNURLOPT_PROTOCOLS.3 b/docs/libcurl/opts/GNURLOPT_PROTOCOLS.3
index fe540720f..417d11958 100644
--- a/docs/libcurl/opts/GNURLOPT_PROTOCOLS.3
+++ b/docs/libcurl/opts/GNURLOPT_PROTOCOLS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY.3 b/docs/libcurl/opts/GNURLOPT_PROXY.3
index 677b038d0..30d1ad47f 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -95,7 +95,7 @@ All except file://. Note that some protocols don't do very well over proxy.
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/file.txt");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/file.txt");
curl_easy_setopt(curl, CURLOPT_PROXY, "http://proxy:80");
curl_easy_perform(curl);
}
diff --git a/docs/libcurl/opts/GNURLOPT_PROXYAUTH.3 b/docs/libcurl/opts/GNURLOPT_PROXYAUTH.3
index 6439eb62a..0be2f299d 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXYAUTH.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXYAUTH.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PROXYHEADER.3 b/docs/libcurl/opts/GNURLOPT_PROXYHEADER.3
index 08f610baa..a4e50e018 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXYHEADER.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXYHEADER.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PROXYPASSWORD.3 b/docs/libcurl/opts/GNURLOPT_PROXYPASSWORD.3
index 04dfbbc96..9159787cf 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXYPASSWORD.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXYPASSWORD.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -44,7 +44,7 @@ Most
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
curl_easy_setopt(curl, CURLOPT_PROXY, "http://localhost:8080");
curl_easy_setopt(curl, CURLOPT_PROXYUSERNAME, "mrsmith");
curl_easy_setopt(curl, CURLOPT_PROXYPASSWORD, "qwerty");
diff --git a/docs/libcurl/opts/GNURLOPT_PROXYPORT.3 b/docs/libcurl/opts/GNURLOPT_PROXYPORT.3
index 75afbbe9e..49274387f 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXYPORT.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXYPORT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -42,7 +42,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
curl_easy_setopt(curl, CURLOPT_PROXY, "localhost");
curl_easy_setopt(curl, CURLOPT_PROXYPORT, 8080L);
ret = curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLOPT_PROXYTYPE.3 b/docs/libcurl/opts/GNURLOPT_PROXYTYPE.3
index 60df0143b..e67977d1c 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXYTYPE.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXYTYPE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PROXYUSERNAME.3 b/docs/libcurl/opts/GNURLOPT_PROXYUSERNAME.3
index 4d85aaa63..0414c368a 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXYUSERNAME.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXYUSERNAME.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -48,7 +48,7 @@ Most
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
curl_easy_setopt(curl, CURLOPT_PROXY, "http://localhost:8080");
curl_easy_setopt(curl, CURLOPT_PROXYUSERNAME, "mrsmith");
curl_easy_setopt(curl, CURLOPT_PROXYPASSWORD, "qwerty");
diff --git a/docs/libcurl/opts/GNURLOPT_PROXYUSERPWD.3 b/docs/libcurl/opts/GNURLOPT_PROXYUSERPWD.3
index 87cdda544..46e9a26e3 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXYUSERPWD.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXYUSERPWD.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -46,7 +46,7 @@ Used with all protocols that can use a proxy
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
curl_easy_setopt(curl, CURLOPT_PROXY, "http://localhost:8080");
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, "clark%20kent:superman");
ret = curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_CAINFO.3 b/docs/libcurl/opts/GNURLOPT_PROXY_CAINFO.3
index 1fb4ca30d..22f2d6b2d 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_CAINFO.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_CAINFO.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -72,7 +72,7 @@ Added in 7.52.0
For TLS backends that don't support certificate files, the
\fICURLOPT_PROXY_CAINFO(3)\fP option is ignored. Refer to
-https://curl.haxx.se/docs/ssl-compared.html
+https://curl.se/docs/ssl-compared.html
.SH RETURN VALUE
Returns CURLE_OK if the option is supported, CURLE_UNKNOWN_OPTION if not, or
CURLE_OUT_OF_MEMORY if there was insufficient heap space.
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_CAPATH.3 b/docs/libcurl/opts/GNURLOPT_PROXY_CAPATH.3
index aed464146..50bc2e10f 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_CAPATH.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_CAPATH.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -67,5 +67,5 @@ CURLE_UNKNOWN_OPTION
CURLE_OUT_OF_MEMORY
.SH "SEE ALSO"
.BR CURLOPT_PROXY_CAINFO "(3), "
-.Br CURLOPT_CAINFO "(3), " CURLOPT_PROXY_SSL_VERIFYHOST "(3), "
+.BR CURLOPT_CAINFO "(3), " CURLOPT_PROXY_SSL_VERIFYHOST "(3), "
.BR CURLOPT_STDERR "(3), " CURLOPT_DEBUGFUNCTION "(3), "
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_CRLFILE.3 b/docs/libcurl/opts/GNURLOPT_PROXY_CRLFILE.3
index 499435c58..72e09b165 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_CRLFILE.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_CRLFILE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_ISSUERCERT.3 b/docs/libcurl/opts/GNURLOPT_PROXY_ISSUERCERT.3
index 6396dddfb..840337b62 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_ISSUERCERT.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_ISSUERCERT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_ISSUERCERT_BLOB.3 b/docs/libcurl/opts/GNURLOPT_PROXY_ISSUERCERT_BLOB.3
index 6165bedf1..bd357da9b 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_ISSUERCERT_BLOB.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_ISSUERCERT_BLOB.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_KEYPASSWD.3 b/docs/libcurl/opts/GNURLOPT_PROXY_KEYPASSWD.3
index 3da1669da..d825642f4 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_KEYPASSWD.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_KEYPASSWD.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -45,7 +45,7 @@ Used with HTTPS proxy
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy:443");
curl_easy_setopt(curl, CURLOPT_PROXY_KEYPASSWD, "superman");
ret = curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_PINNEDPUBLICKEY.3 b/docs/libcurl/opts/GNURLOPT_PROXY_PINNEDPUBLICKEY.3
index f0b344630..0b02bac9e 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_PINNEDPUBLICKEY.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_PINNEDPUBLICKEY.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_SERVICE_NAME.3 b/docs/libcurl/opts/GNURLOPT_PROXY_SERVICE_NAME.3
index 875a90440..fc7182d4b 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_SERVICE_NAME.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_SERVICE_NAME.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_SSLCERT.3 b/docs/libcurl/opts/GNURLOPT_PROXY_SSLCERT.3
index 677225eef..f670f0070 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_SSLCERT.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_SSLCERT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_SSLCERTTYPE.3 b/docs/libcurl/opts/GNURLOPT_PROXY_SSLCERTTYPE.3
index b0ecc2b15..8f3525c7f 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_SSLCERTTYPE.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_SSLCERTTYPE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_SSLCERT_BLOB.3 b/docs/libcurl/opts/GNURLOPT_PROXY_SSLCERT_BLOB.3
index 4e7fc427b..76c9f6b7b 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_SSLCERT_BLOB.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_SSLCERT_BLOB.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_SSLKEY.3 b/docs/libcurl/opts/GNURLOPT_PROXY_SSLKEY.3
index e8bcaab66..3cff36a5f 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_SSLKEY.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_SSLKEY.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_SSLKEYTYPE.3 b/docs/libcurl/opts/GNURLOPT_PROXY_SSLKEYTYPE.3
index 344db1223..c72dbb9e1 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_SSLKEYTYPE.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_SSLKEYTYPE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_SSLKEY_BLOB.3 b/docs/libcurl/opts/GNURLOPT_PROXY_SSLKEY_BLOB.3
index 7431f3261..7ad093712 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_SSLKEY_BLOB.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_SSLKEY_BLOB.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_SSLVERSION.3 b/docs/libcurl/opts/GNURLOPT_PROXY_SSLVERSION.3
index 7d3b0f5aa..d7f914d0b 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_SSLVERSION.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_SSLVERSION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_SSL_CIPHER_LIST.3 b/docs/libcurl/opts/GNURLOPT_PROXY_SSL_CIPHER_LIST.3
index bf40f318a..06b72625c 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_SSL_CIPHER_LIST.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_SSL_CIPHER_LIST.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_SSL_OPTIONS.3 b/docs/libcurl/opts/GNURLOPT_PROXY_SSL_OPTIONS.3
index 2f40b6bbb..221dee592 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_SSL_OPTIONS.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_SSL_OPTIONS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_SSL_VERIFYHOST.3 b/docs/libcurl/opts/GNURLOPT_PROXY_SSL_VERIFYHOST.3
index afcc51413..462a33e3e 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_SSL_VERIFYHOST.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_SSL_VERIFYHOST.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_SSL_VERIFYPEER.3 b/docs/libcurl/opts/GNURLOPT_PROXY_SSL_VERIFYPEER.3
index 656e6d8e5..9489df35c 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_SSL_VERIFYPEER.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_SSL_VERIFYPEER.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_TLS13_CIPHERS.3 b/docs/libcurl/opts/GNURLOPT_PROXY_TLS13_CIPHERS.3
index eb6ee937d..97714d3cd 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_TLS13_CIPHERS.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_TLS13_CIPHERS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -35,7 +35,7 @@ separated by colons.
You'll find more details about cipher lists on this URL:
- https://curl.haxx.se/docs/ssl-ciphers.html
+ https://curl.se/docs/ssl-ciphers.html
This option is currently used only when curl is built to use OpenSSL 1.1.1 or
later. If you are using a different SSL backend you can try setting TLS 1.3
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_TLSAUTH_PASSWORD.3 b/docs/libcurl/opts/GNURLOPT_PROXY_TLSAUTH_PASSWORD.3
index 464916e81..33991eec8 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_TLSAUTH_PASSWORD.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_TLSAUTH_PASSWORD.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_TLSAUTH_TYPE.3 b/docs/libcurl/opts/GNURLOPT_PROXY_TLSAUTH_TYPE.3
index dc4bfa90f..a16dd1e38 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_TLSAUTH_TYPE.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_TLSAUTH_TYPE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_TLSAUTH_USERNAME.3 b/docs/libcurl/opts/GNURLOPT_PROXY_TLSAUTH_USERNAME.3
index 742f206c4..0bf12479c 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_TLSAUTH_USERNAME.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_TLSAUTH_USERNAME.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PROXY_TRANSFER_MODE.3 b/docs/libcurl/opts/GNURLOPT_PROXY_TRANSFER_MODE.3
index 66fbdcc65..0919de9b7 100644
--- a/docs/libcurl/opts/GNURLOPT_PROXY_TRANSFER_MODE.3
+++ b/docs/libcurl/opts/GNURLOPT_PROXY_TRANSFER_MODE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_PUT.3 b/docs/libcurl/opts/GNURLOPT_PUT.3
index 54cf0400c..8c6e367b3 100644
--- a/docs/libcurl/opts/GNURLOPT_PUT.3
+++ b/docs/libcurl/opts/GNURLOPT_PUT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_QUOTE.3 b/docs/libcurl/opts/GNURLOPT_QUOTE.3
index a429b72b0..96ba48ac9 100644
--- a/docs/libcurl/opts/GNURLOPT_QUOTE.3
+++ b/docs/libcurl/opts/GNURLOPT_QUOTE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -43,6 +43,10 @@ mandatory commands).
The valid SFTP commands are:
.RS
+.IP "atime date file"
+The atime command sets the last access time of the file named by the file
+operand. The <date expression> can be all sorts of date strings, see the
+\fIcurl_getdate(3)\fP man page for date expression details. (Added in 7.73.0)
.IP "chgrp group file"
The chgrp command sets the group ID of the file named by the file operand to
the group ID specified by the group operand. The group operand is a decimal
@@ -59,6 +63,10 @@ The ln and symlink commands create a symbolic link at the target_file location
pointing to the source_file location.
.IP "mkdir directory_name"
The mkdir command creates the directory named by the directory_name operand.
+.IP "mtime date file"
+The mtime command sets the last modification time of the file named by the
+file operand. The <date expression> can be all sorts of date strings, see the
+\fIcurl_getdate(3)\fP man page for date expression details. (Added in 7.73.0)
.IP "pwd"
The pwd command returns the absolute pathname of the current working directory.
.IP "rename source target"
diff --git a/docs/libcurl/opts/GNURLOPT_RANDOM_FILE.3 b/docs/libcurl/opts/GNURLOPT_RANDOM_FILE.3
index f5939d21d..54b8eac4a 100644
--- a/docs/libcurl/opts/GNURLOPT_RANDOM_FILE.3
+++ b/docs/libcurl/opts/GNURLOPT_RANDOM_FILE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_RANGE.3 b/docs/libcurl/opts/GNURLOPT_RANGE.3
index 4311ad1e9..6055d60ad 100644
--- a/docs/libcurl/opts/GNURLOPT_RANGE.3
+++ b/docs/libcurl/opts/GNURLOPT_RANGE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -49,7 +49,7 @@ Amazon's web services) support is limited. We suggest set resume position using
\fICURLOPT_RESUME_FROM(3)\fP, set end (resume+size) position using
\fICURLOPT_INFILESIZE(3)\fP and seek to the resume position before initiating
the transfer for each part. For more information refer to
-https://curl.haxx.se/mail/lib-2019-05/0012.html
+https://curl.se/mail/lib-2019-05/0012.html
Pass a NULL to this option to disable the use of ranges.
@@ -63,7 +63,7 @@ HTTP, FTP, FILE, RTSP and SFTP.
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* get the first 200 bytes */
curl_easy_setopt(curl, CURLOPT_RANGE, "0-199");
diff --git a/docs/libcurl/opts/GNURLOPT_READDATA.3 b/docs/libcurl/opts/GNURLOPT_READDATA.3
index 9b532248d..c47e518c1 100644
--- a/docs/libcurl/opts/GNURLOPT_READDATA.3
+++ b/docs/libcurl/opts/GNURLOPT_READDATA.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -47,7 +47,7 @@ This is used for all protocols when sending data.
CURL *curl = curl_easy_init();
struct MyData this;
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* pass pointer that gets passed in to the
CURLOPT_READFUNCTION callback */
diff --git a/docs/libcurl/opts/GNURLOPT_READFUNCTION.3 b/docs/libcurl/opts/GNURLOPT_READFUNCTION.3
index e0e3b255f..7b8a4ea64 100644
--- a/docs/libcurl/opts/GNURLOPT_READFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_READFUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_REDIR_PROTOCOLS.3 b/docs/libcurl/opts/GNURLOPT_REDIR_PROTOCOLS.3
index 3a9f07475..9ba8892da 100644
--- a/docs/libcurl/opts/GNURLOPT_REDIR_PROTOCOLS.3
+++ b/docs/libcurl/opts/GNURLOPT_REDIR_PROTOCOLS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_REFERER.3 b/docs/libcurl/opts/GNURLOPT_REFERER.3
index 059a9d3e4..4f9e99fcc 100644
--- a/docs/libcurl/opts/GNURLOPT_REFERER.3
+++ b/docs/libcurl/opts/GNURLOPT_REFERER.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -43,10 +43,10 @@ HTTP
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* tell it where we found the link to this place */
- curl_easy_setopt(curl, CURLOPT_REFERER, "http://example.com/aboutme.html");
+ curl_easy_setopt(curl, CURLOPT_REFERER, "https://example.com/aboutme.html");
curl_easy_perform(curl);
}
diff --git a/docs/libcurl/opts/GNURLOPT_REQUEST_TARGET.3 b/docs/libcurl/opts/GNURLOPT_REQUEST_TARGET.3
index e7124e5aa..a30ab3370 100644
--- a/docs/libcurl/opts/GNURLOPT_REQUEST_TARGET.3
+++ b/docs/libcurl/opts/GNURLOPT_REQUEST_TARGET.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -38,7 +38,7 @@ HTTP
.nf
curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/*");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/*");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "OPTIONS");
/* issue an OPTIONS * request (no leading slash) */
diff --git a/docs/libcurl/opts/GNURLOPT_RESOLVE.3 b/docs/libcurl/opts/GNURLOPT_RESOLVE.3
index 5a064eca4..4a0373207 100644
--- a/docs/libcurl/opts/GNURLOPT_RESOLVE.3
+++ b/docs/libcurl/opts/GNURLOPT_RESOLVE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -79,7 +79,7 @@ host = curl_slist_append(NULL, "example.com:80:127.0.0.1");
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_RESOLVE, host);
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLOPT_RESOLVER_START_DATA.3 b/docs/libcurl/opts/GNURLOPT_RESOLVER_START_DATA.3
index 31ecf8e88..3bbc252dd 100644
--- a/docs/libcurl/opts/GNURLOPT_RESOLVER_START_DATA.3
+++ b/docs/libcurl/opts/GNURLOPT_RESOLVER_START_DATA.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -50,7 +50,7 @@ CURL *curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_RESOLVER_START_FUNCTION, resolver_start_cb);
curl_easy_setopt(curl, CURLOPT_RESOLVER_START_DATA, curl);
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
diff --git a/docs/libcurl/opts/GNURLOPT_RESOLVER_START_FUNCTION.3 b/docs/libcurl/opts/GNURLOPT_RESOLVER_START_FUNCTION.3
index 9adcfca89..504646d4c 100644
--- a/docs/libcurl/opts/GNURLOPT_RESOLVER_START_FUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_RESOLVER_START_FUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -70,7 +70,7 @@ CURL *curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_RESOLVER_START_FUNCTION, resolver_start_cb);
curl_easy_setopt(curl, CURLOPT_RESOLVER_START_DATA, curl);
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
diff --git a/docs/libcurl/opts/GNURLOPT_RESUME_FROM.3 b/docs/libcurl/opts/GNURLOPT_RESUME_FROM.3
index 4e3d06f91..c070b39ca 100644
--- a/docs/libcurl/opts/GNURLOPT_RESUME_FROM.3
+++ b/docs/libcurl/opts/GNURLOPT_RESUME_FROM.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_RESUME_FROM_LARGE.3 b/docs/libcurl/opts/GNURLOPT_RESUME_FROM_LARGE.3
index 1f38993f4..f47b64f26 100644
--- a/docs/libcurl/opts/GNURLOPT_RESUME_FROM_LARGE.3
+++ b/docs/libcurl/opts/GNURLOPT_RESUME_FROM_LARGE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_RTSP_CLIENT_CSEQ.3 b/docs/libcurl/opts/GNURLOPT_RTSP_CLIENT_CSEQ.3
index 2dd0a545a..99b926b4f 100644
--- a/docs/libcurl/opts/GNURLOPT_RTSP_CLIENT_CSEQ.3
+++ b/docs/libcurl/opts/GNURLOPT_RTSP_CLIENT_CSEQ.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_RTSP_REQUEST.3 b/docs/libcurl/opts/GNURLOPT_RTSP_REQUEST.3
index 5bd47a309..973683daf 100644
--- a/docs/libcurl/opts/GNURLOPT_RTSP_REQUEST.3
+++ b/docs/libcurl/opts/GNURLOPT_RTSP_REQUEST.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_RTSP_SERVER_CSEQ.3 b/docs/libcurl/opts/GNURLOPT_RTSP_SERVER_CSEQ.3
index b881255f4..53a9b433e 100644
--- a/docs/libcurl/opts/GNURLOPT_RTSP_SERVER_CSEQ.3
+++ b/docs/libcurl/opts/GNURLOPT_RTSP_SERVER_CSEQ.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_RTSP_SESSION_ID.3 b/docs/libcurl/opts/GNURLOPT_RTSP_SESSION_ID.3
index ee4805e05..1f5e2d596 100644
--- a/docs/libcurl/opts/GNURLOPT_RTSP_SESSION_ID.3
+++ b/docs/libcurl/opts/GNURLOPT_RTSP_SESSION_ID.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_RTSP_STREAM_URI.3 b/docs/libcurl/opts/GNURLOPT_RTSP_STREAM_URI.3
index 9d9a00478..d91d8d4fd 100644
--- a/docs/libcurl/opts/GNURLOPT_RTSP_STREAM_URI.3
+++ b/docs/libcurl/opts/GNURLOPT_RTSP_STREAM_URI.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_RTSP_TRANSPORT.3 b/docs/libcurl/opts/GNURLOPT_RTSP_TRANSPORT.3
index d3efe6621..adef96a2c 100644
--- a/docs/libcurl/opts/GNURLOPT_RTSP_TRANSPORT.3
+++ b/docs/libcurl/opts/GNURLOPT_RTSP_TRANSPORT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SASL_AUTHZID.3 b/docs/libcurl/opts/GNURLOPT_SASL_AUTHZID.3
index 86aa7901f..38422c636 100644
--- a/docs/libcurl/opts/GNURLOPT_SASL_AUTHZID.3
+++ b/docs/libcurl/opts/GNURLOPT_SASL_AUTHZID.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SASL_IR.3 b/docs/libcurl/opts/GNURLOPT_SASL_IR.3
index 51649d589..352e7d01c 100644
--- a/docs/libcurl/opts/GNURLOPT_SASL_IR.3
+++ b/docs/libcurl/opts/GNURLOPT_SASL_IR.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SEEKDATA.3 b/docs/libcurl/opts/GNURLOPT_SEEKDATA.3
index eb73a1a01..2f0bbe4d2 100644
--- a/docs/libcurl/opts/GNURLOPT_SEEKDATA.3
+++ b/docs/libcurl/opts/GNURLOPT_SEEKDATA.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SEEKFUNCTION.3 b/docs/libcurl/opts/GNURLOPT_SEEKFUNCTION.3
index 3d4ad7403..83fa47b95 100644
--- a/docs/libcurl/opts/GNURLOPT_SEEKFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_SEEKFUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SERVICE_NAME.3 b/docs/libcurl/opts/GNURLOPT_SERVICE_NAME.3
index eaed26490..979310e58 100644
--- a/docs/libcurl/opts/GNURLOPT_SERVICE_NAME.3
+++ b/docs/libcurl/opts/GNURLOPT_SERVICE_NAME.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SHARE.3 b/docs/libcurl/opts/GNURLOPT_SHARE.3
index f9f32c823..90398ed42 100644
--- a/docs/libcurl/opts/GNURLOPT_SHARE.3
+++ b/docs/libcurl/opts/GNURLOPT_SHARE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SOCKOPTDATA.3 b/docs/libcurl/opts/GNURLOPT_SOCKOPTDATA.3
index 8ccadd55f..39419f91a 100644
--- a/docs/libcurl/opts/GNURLOPT_SOCKOPTDATA.3
+++ b/docs/libcurl/opts/GNURLOPT_SOCKOPTDATA.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -48,7 +48,7 @@ curl = curl_easy_init();
if(curl) {
int recvbuffersize = 256 * 1024;
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
/* call this function to set options for the socket */
curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback);
diff --git a/docs/libcurl/opts/GNURLOPT_SOCKOPTFUNCTION.3 b/docs/libcurl/opts/GNURLOPT_SOCKOPTFUNCTION.3
index be9f84285..7553690e3 100644
--- a/docs/libcurl/opts/GNURLOPT_SOCKOPTFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_SOCKOPTFUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SOCKS5_AUTH.3 b/docs/libcurl/opts/GNURLOPT_SOCKS5_AUTH.3
index 9c9fb158f..23719f11d 100644
--- a/docs/libcurl/opts/GNURLOPT_SOCKS5_AUTH.3
+++ b/docs/libcurl/opts/GNURLOPT_SOCKS5_AUTH.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SOCKS5_GSSAPI_NEC.3 b/docs/libcurl/opts/GNURLOPT_SOCKS5_GSSAPI_NEC.3
index b752977cb..1e5d9107f 100644
--- a/docs/libcurl/opts/GNURLOPT_SOCKS5_GSSAPI_NEC.3
+++ b/docs/libcurl/opts/GNURLOPT_SOCKS5_GSSAPI_NEC.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SOCKS5_GSSAPI_SERVICE.3 b/docs/libcurl/opts/GNURLOPT_SOCKS5_GSSAPI_SERVICE.3
index ae16eedbd..68a05fa01 100644
--- a/docs/libcurl/opts/GNURLOPT_SOCKS5_GSSAPI_SERVICE.3
+++ b/docs/libcurl/opts/GNURLOPT_SOCKS5_GSSAPI_SERVICE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSH_AUTH_TYPES.3 b/docs/libcurl/opts/GNURLOPT_SSH_AUTH_TYPES.3
index db943444e..22f3f0253 100644
--- a/docs/libcurl/opts/GNURLOPT_SSH_AUTH_TYPES.3
+++ b/docs/libcurl/opts/GNURLOPT_SSH_AUTH_TYPES.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSH_COMPRESSION.3 b/docs/libcurl/opts/GNURLOPT_SSH_COMPRESSION.3
index 92a80a3fd..e1d27bd69 100644
--- a/docs/libcurl/opts/GNURLOPT_SSH_COMPRESSION.3
+++ b/docs/libcurl/opts/GNURLOPT_SSH_COMPRESSION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSH_HOST_PUBLIC_KEY_MD5.3 b/docs/libcurl/opts/GNURLOPT_SSH_HOST_PUBLIC_KEY_MD5.3
index 91716423f..891752984 100644
--- a/docs/libcurl/opts/GNURLOPT_SSH_HOST_PUBLIC_KEY_MD5.3
+++ b/docs/libcurl/opts/GNURLOPT_SSH_HOST_PUBLIC_KEY_MD5.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSH_KEYDATA.3 b/docs/libcurl/opts/GNURLOPT_SSH_KEYDATA.3
index 1037947e8..b088cf462 100644
--- a/docs/libcurl/opts/GNURLOPT_SSH_KEYDATA.3
+++ b/docs/libcurl/opts/GNURLOPT_SSH_KEYDATA.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSH_KEYFUNCTION.3 b/docs/libcurl/opts/GNURLOPT_SSH_KEYFUNCTION.3
index 76119c34a..144f61c1f 100644
--- a/docs/libcurl/opts/GNURLOPT_SSH_KEYFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_SSH_KEYFUNCTION.3
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -35,6 +35,7 @@ enum curl_khstat {
now so this causes a CURLE_DEFER error but
otherwise the connection will be left intact
etc */
+ CURLKHSTAT_FINE_REPLACE
};
enum curl_khmatch {
@@ -72,7 +73,13 @@ known_hosts file \fIknownkey\fP, the key from the remote site \fIfoundkey\fP,
info from libcurl on the matching status and a custom pointer (set with
\fICURLOPT_SSH_KEYDATA(3)\fP). It MUST return one of the following return
codes to tell libcurl how to act:
-
+.IP CURLKHSTAT_FINE_REPLACE
+The new host+key is accepted and libcurl will replace the old host+key into
+the known_hosts file before continuing with the connection. This will also
+add the new host+key combo to the known_host pool kept in memory if it wasn't
+already present there. The adding of data to the file is done by completely
+replacing the file with a new copy, so the permissions of the file must allow
+this. (Added in 7.73.0)
.IP CURLKHSTAT_FINE_ADD_TO_FILE
The host+key is accepted and libcurl will append it to the known_hosts file
before continuing with the connection. This will also add the host+key combo
diff --git a/docs/libcurl/opts/GNURLOPT_SSH_KNOWNHOSTS.3 b/docs/libcurl/opts/GNURLOPT_SSH_KNOWNHOSTS.3
index 86be0617c..f78f8630b 100644
--- a/docs/libcurl/opts/GNURLOPT_SSH_KNOWNHOSTS.3
+++ b/docs/libcurl/opts/GNURLOPT_SSH_KNOWNHOSTS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSH_PRIVATE_KEYFILE.3 b/docs/libcurl/opts/GNURLOPT_SSH_PRIVATE_KEYFILE.3
index 079519598..f9d9c66e2 100644
--- a/docs/libcurl/opts/GNURLOPT_SSH_PRIVATE_KEYFILE.3
+++ b/docs/libcurl/opts/GNURLOPT_SSH_PRIVATE_KEYFILE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSH_PUBLIC_KEYFILE.3 b/docs/libcurl/opts/GNURLOPT_SSH_PUBLIC_KEYFILE.3
index 38cae0ca8..fe0ecda60 100644
--- a/docs/libcurl/opts/GNURLOPT_SSH_PUBLIC_KEYFILE.3
+++ b/docs/libcurl/opts/GNURLOPT_SSH_PUBLIC_KEYFILE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSLCERT.3 b/docs/libcurl/opts/GNURLOPT_SSLCERT.3
index ce462280c..68f48e6a6 100644
--- a/docs/libcurl/opts/GNURLOPT_SSLCERT.3
+++ b/docs/libcurl/opts/GNURLOPT_SSLCERT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSLCERTTYPE.3 b/docs/libcurl/opts/GNURLOPT_SSLCERTTYPE.3
index 3947324fa..79ff167e3 100644
--- a/docs/libcurl/opts/GNURLOPT_SSLCERTTYPE.3
+++ b/docs/libcurl/opts/GNURLOPT_SSLCERTTYPE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSLCERT_BLOB.3 b/docs/libcurl/opts/GNURLOPT_SSLCERT_BLOB.3
index da278224f..c0ec71ec1 100644
--- a/docs/libcurl/opts/GNURLOPT_SSLCERT_BLOB.3
+++ b/docs/libcurl/opts/GNURLOPT_SSLCERT_BLOB.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSLENGINE.3 b/docs/libcurl/opts/GNURLOPT_SSLENGINE.3
index ba3e3007c..825129d5e 100644
--- a/docs/libcurl/opts/GNURLOPT_SSLENGINE.3
+++ b/docs/libcurl/opts/GNURLOPT_SSLENGINE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSLENGINE_DEFAULT.3 b/docs/libcurl/opts/GNURLOPT_SSLENGINE_DEFAULT.3
index f45ad371d..45a4c82ce 100644
--- a/docs/libcurl/opts/GNURLOPT_SSLENGINE_DEFAULT.3
+++ b/docs/libcurl/opts/GNURLOPT_SSLENGINE_DEFAULT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSLKEY.3 b/docs/libcurl/opts/GNURLOPT_SSLKEY.3
index cc54f6b83..ac2c75560 100644
--- a/docs/libcurl/opts/GNURLOPT_SSLKEY.3
+++ b/docs/libcurl/opts/GNURLOPT_SSLKEY.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSLKEYTYPE.3 b/docs/libcurl/opts/GNURLOPT_SSLKEYTYPE.3
index 1ec2db1a1..1db4d314e 100644
--- a/docs/libcurl/opts/GNURLOPT_SSLKEYTYPE.3
+++ b/docs/libcurl/opts/GNURLOPT_SSLKEYTYPE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSLKEY_BLOB.3 b/docs/libcurl/opts/GNURLOPT_SSLKEY_BLOB.3
index 34688f653..2f74a9cce 100644
--- a/docs/libcurl/opts/GNURLOPT_SSLKEY_BLOB.3
+++ b/docs/libcurl/opts/GNURLOPT_SSLKEY_BLOB.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSLVERSION.3 b/docs/libcurl/opts/GNURLOPT_SSLVERSION.3
index 60629ddf6..810dcd4f4 100644
--- a/docs/libcurl/opts/GNURLOPT_SSLVERSION.3
+++ b/docs/libcurl/opts/GNURLOPT_SSLVERSION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSL_CIPHER_LIST.3 b/docs/libcurl/opts/GNURLOPT_SSL_CIPHER_LIST.3
index 2fb8a52d6..3dc883158 100644
--- a/docs/libcurl/opts/GNURLOPT_SSL_CIPHER_LIST.3
+++ b/docs/libcurl/opts/GNURLOPT_SSL_CIPHER_LIST.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -40,7 +40,7 @@ compile OpenSSL.
You'll find more details about cipher lists on this URL:
- https://curl.haxx.se/docs/ssl-ciphers.html
+ https://curl.se/docs/ssl-ciphers.html
For NSS, valid examples of cipher lists include 'rsa_rc4_128_md5',
\'rsa_aes_128_sha\', etc. With NSS you don't add/remove ciphers. If one uses
diff --git a/docs/libcurl/opts/GNURLOPT_SSL_CTX_DATA.3 b/docs/libcurl/opts/GNURLOPT_SSL_CTX_DATA.3
index 166bb866e..5c6d16d6b 100644
--- a/docs/libcurl/opts/GNURLOPT_SSL_CTX_DATA.3
+++ b/docs/libcurl/opts/GNURLOPT_SSL_CTX_DATA.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSL_CTX_FUNCTION.3 b/docs/libcurl/opts/GNURLOPT_SSL_CTX_FUNCTION.3
index 49dd2ecf1..8162571bb 100644
--- a/docs/libcurl/opts/GNURLOPT_SSL_CTX_FUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_SSL_CTX_FUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -69,7 +69,7 @@ All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc.
.SH EXAMPLE
See cacertinmem.c in docs/examples directory for usage example.
-https://curl.haxx.se/libcurl/c/cacertinmem.html
+https://curl.se/libcurl/c/cacertinmem.html
.SH AVAILABILITY
Added in 7.11.0 for OpenSSL, in 7.42.0 for wolfSSL and in 7.54.0 for
mbedTLS. Other SSL backends are not supported.
diff --git a/docs/libcurl/opts/GNURLOPT_SSL_ENABLE_ALPN.3 b/docs/libcurl/opts/GNURLOPT_SSL_ENABLE_ALPN.3
index 83122beae..24aade5fa 100644
--- a/docs/libcurl/opts/GNURLOPT_SSL_ENABLE_ALPN.3
+++ b/docs/libcurl/opts/GNURLOPT_SSL_ENABLE_ALPN.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSL_ENABLE_NPN.3 b/docs/libcurl/opts/GNURLOPT_SSL_ENABLE_NPN.3
index 4a3c9f01e..e46de3c4a 100644
--- a/docs/libcurl/opts/GNURLOPT_SSL_ENABLE_NPN.3
+++ b/docs/libcurl/opts/GNURLOPT_SSL_ENABLE_NPN.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSL_FALSESTART.3 b/docs/libcurl/opts/GNURLOPT_SSL_FALSESTART.3
index de391ebe2..215504ca7 100644
--- a/docs/libcurl/opts/GNURLOPT_SSL_FALSESTART.3
+++ b/docs/libcurl/opts/GNURLOPT_SSL_FALSESTART.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSL_OPTIONS.3 b/docs/libcurl/opts/GNURLOPT_SSL_OPTIONS.3
index b12405033..9f2849bf2 100644
--- a/docs/libcurl/opts/GNURLOPT_SSL_OPTIONS.3
+++ b/docs/libcurl/opts/GNURLOPT_SSL_OPTIONS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSL_SESSIONID_CACHE.3 b/docs/libcurl/opts/GNURLOPT_SSL_SESSIONID_CACHE.3
index d691c1020..00b38cd07 100644
--- a/docs/libcurl/opts/GNURLOPT_SSL_SESSIONID_CACHE.3
+++ b/docs/libcurl/opts/GNURLOPT_SSL_SESSIONID_CACHE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSL_VERIFYHOST.3 b/docs/libcurl/opts/GNURLOPT_SSL_VERIFYHOST.3
index 810c2a83f..730758715 100644
--- a/docs/libcurl/opts/GNURLOPT_SSL_VERIFYHOST.3
+++ b/docs/libcurl/opts/GNURLOPT_SSL_VERIFYHOST.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSL_VERIFYPEER.3 b/docs/libcurl/opts/GNURLOPT_SSL_VERIFYPEER.3
index 55636bfbb..5c2a27f41 100644
--- a/docs/libcurl/opts/GNURLOPT_SSL_VERIFYPEER.3
+++ b/docs/libcurl/opts/GNURLOPT_SSL_VERIFYPEER.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SSL_VERIFYSTATUS.3 b/docs/libcurl/opts/GNURLOPT_SSL_VERIFYSTATUS.3
index 824c9669b..80faa038a 100644
--- a/docs/libcurl/opts/GNURLOPT_SSL_VERIFYSTATUS.3
+++ b/docs/libcurl/opts/GNURLOPT_SSL_VERIFYSTATUS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_STDERR.3 b/docs/libcurl/opts/GNURLOPT_STDERR.3
index c2758d54a..bae91971f 100644
--- a/docs/libcurl/opts/GNURLOPT_STDERR.3
+++ b/docs/libcurl/opts/GNURLOPT_STDERR.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -40,7 +40,7 @@ All
CURL *curl = curl_easy_init();
FILE *filep = fopen("dump", "wb");
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_setopt(curl, CURLOPT_STDERR, filep);
curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLOPT_STREAM_DEPENDS.3 b/docs/libcurl/opts/GNURLOPT_STREAM_DEPENDS.3
index eef13ee5b..c50685067 100644
--- a/docs/libcurl/opts/GNURLOPT_STREAM_DEPENDS.3
+++ b/docs/libcurl/opts/GNURLOPT_STREAM_DEPENDS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_STREAM_DEPENDS_E.3 b/docs/libcurl/opts/GNURLOPT_STREAM_DEPENDS_E.3
index 128ae5e65..3511b7021 100644
--- a/docs/libcurl/opts/GNURLOPT_STREAM_DEPENDS_E.3
+++ b/docs/libcurl/opts/GNURLOPT_STREAM_DEPENDS_E.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_STREAM_WEIGHT.3 b/docs/libcurl/opts/GNURLOPT_STREAM_WEIGHT.3
index 2d4fa9f6b..cea8e7dab 100644
--- a/docs/libcurl/opts/GNURLOPT_STREAM_WEIGHT.3
+++ b/docs/libcurl/opts/GNURLOPT_STREAM_WEIGHT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_SUPPRESS_CONNECT_HEADERS.3 b/docs/libcurl/opts/GNURLOPT_SUPPRESS_CONNECT_HEADERS.3
index 9f5eef95b..84d55ee8a 100644
--- a/docs/libcurl/opts/GNURLOPT_SUPPRESS_CONNECT_HEADERS.3
+++ b/docs/libcurl/opts/GNURLOPT_SUPPRESS_CONNECT_HEADERS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_TCP_FASTOPEN.3 b/docs/libcurl/opts/GNURLOPT_TCP_FASTOPEN.3
index 7dc62263c..ccaa03b15 100644
--- a/docs/libcurl/opts/GNURLOPT_TCP_FASTOPEN.3
+++ b/docs/libcurl/opts/GNURLOPT_TCP_FASTOPEN.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -41,7 +41,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_setopt(curl, CURLOPT_TCP_FASTOPEN, 1L);
curl_easy_perform(curl);
}
diff --git a/docs/libcurl/opts/GNURLOPT_TCP_KEEPALIVE.3 b/docs/libcurl/opts/GNURLOPT_TCP_KEEPALIVE.3
index 155f5e1c5..91e86aaae 100644
--- a/docs/libcurl/opts/GNURLOPT_TCP_KEEPALIVE.3
+++ b/docs/libcurl/opts/GNURLOPT_TCP_KEEPALIVE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -41,7 +41,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* enable TCP keep-alive for this transfer */
curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
diff --git a/docs/libcurl/opts/GNURLOPT_TCP_KEEPIDLE.3 b/docs/libcurl/opts/GNURLOPT_TCP_KEEPIDLE.3
index 08f7934c1..f7da4c3b2 100644
--- a/docs/libcurl/opts/GNURLOPT_TCP_KEEPIDLE.3
+++ b/docs/libcurl/opts/GNURLOPT_TCP_KEEPIDLE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -39,7 +39,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* enable TCP keep-alive for this transfer */
curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
diff --git a/docs/libcurl/opts/GNURLOPT_TCP_KEEPINTVL.3 b/docs/libcurl/opts/GNURLOPT_TCP_KEEPINTVL.3
index d9e23b603..b553434e6 100644
--- a/docs/libcurl/opts/GNURLOPT_TCP_KEEPINTVL.3
+++ b/docs/libcurl/opts/GNURLOPT_TCP_KEEPINTVL.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -39,7 +39,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* enable TCP keep-alive for this transfer */
curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
diff --git a/docs/libcurl/opts/GNURLOPT_TCP_NODELAY.3 b/docs/libcurl/opts/GNURLOPT_TCP_NODELAY.3
index dd6fb6251..39615f8c7 100644
--- a/docs/libcurl/opts/GNURLOPT_TCP_NODELAY.3
+++ b/docs/libcurl/opts/GNURLOPT_TCP_NODELAY.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -50,8 +50,8 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
- /* disable Nagle */
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
+ /* leave Nagle enabled */
curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 0);
curl_easy_perform(curl);
}
diff --git a/docs/libcurl/opts/GNURLOPT_TELNETOPTIONS.3 b/docs/libcurl/opts/GNURLOPT_TELNETOPTIONS.3
index 8b3751cc3..85f807872 100644
--- a/docs/libcurl/opts/GNURLOPT_TELNETOPTIONS.3
+++ b/docs/libcurl/opts/GNURLOPT_TELNETOPTIONS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_TFTP_BLKSIZE.3 b/docs/libcurl/opts/GNURLOPT_TFTP_BLKSIZE.3
index e4ae6df2b..95a2e3c18 100644
--- a/docs/libcurl/opts/GNURLOPT_TFTP_BLKSIZE.3
+++ b/docs/libcurl/opts/GNURLOPT_TFTP_BLKSIZE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_TFTP_NO_OPTIONS.3 b/docs/libcurl/opts/GNURLOPT_TFTP_NO_OPTIONS.3
index 5107aa58e..38e306fa1 100644
--- a/docs/libcurl/opts/GNURLOPT_TFTP_NO_OPTIONS.3
+++ b/docs/libcurl/opts/GNURLOPT_TFTP_NO_OPTIONS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_TIMECONDITION.3 b/docs/libcurl/opts/GNURLOPT_TIMECONDITION.3
index fcfcd0846..1ddeeef53 100644
--- a/docs/libcurl/opts/GNURLOPT_TIMECONDITION.3
+++ b/docs/libcurl/opts/GNURLOPT_TIMECONDITION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -45,7 +45,7 @@ HTTP, FTP, RTSP, and FILE
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* January 1, 2020 is 1577833200 */
curl_easy_setopt(curl, CURLOPT_TIMEVALUE, 1577833200L);
diff --git a/docs/libcurl/opts/GNURLOPT_TIMEOUT.3 b/docs/libcurl/opts/GNURLOPT_TIMEOUT.3
index c6c3bc95e..8276c1989 100644
--- a/docs/libcurl/opts/GNURLOPT_TIMEOUT.3
+++ b/docs/libcurl/opts/GNURLOPT_TIMEOUT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -54,7 +54,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* complete within 20 seconds */
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 20L);
diff --git a/docs/libcurl/opts/GNURLOPT_TIMEOUT_MS.3 b/docs/libcurl/opts/GNURLOPT_TIMEOUT_MS.3
index 8bd7b8651..751749933 100644
--- a/docs/libcurl/opts/GNURLOPT_TIMEOUT_MS.3
+++ b/docs/libcurl/opts/GNURLOPT_TIMEOUT_MS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -57,7 +57,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* complete within 20000 milliseconds */
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 20000L);
diff --git a/docs/libcurl/opts/GNURLOPT_TIMEVALUE.3 b/docs/libcurl/opts/GNURLOPT_TIMEVALUE.3
index c333ca65d..a6afeaa8b 100644
--- a/docs/libcurl/opts/GNURLOPT_TIMEVALUE.3
+++ b/docs/libcurl/opts/GNURLOPT_TIMEVALUE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -42,7 +42,7 @@ HTTP, FTP, RTSP, and FILE
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* January 1, 2020 is 1577833200 */
curl_easy_setopt(curl, CURLOPT_TIMEVALUE, 1577833200L);
diff --git a/docs/libcurl/opts/GNURLOPT_TIMEVALUE_LARGE.3 b/docs/libcurl/opts/GNURLOPT_TIMEVALUE_LARGE.3
index 1e13a9020..9a5c051de 100644
--- a/docs/libcurl/opts/GNURLOPT_TIMEVALUE_LARGE.3
+++ b/docs/libcurl/opts/GNURLOPT_TIMEVALUE_LARGE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -43,7 +43,7 @@ HTTP, FTP, RTSP, and FILE
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* January 1, 2020 is 1577833200 */
curl_easy_setopt(curl, CURLOPT_TIMEVALUE_LARGE, (curl_off_t)1577833200);
diff --git a/docs/libcurl/opts/GNURLOPT_TLS13_CIPHERS.3 b/docs/libcurl/opts/GNURLOPT_TLS13_CIPHERS.3
index 878e10806..11757bbc5 100644
--- a/docs/libcurl/opts/GNURLOPT_TLS13_CIPHERS.3
+++ b/docs/libcurl/opts/GNURLOPT_TLS13_CIPHERS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -34,7 +34,7 @@ correct, it consists of one or more cipher suite strings separated by colons.
You'll find more details about cipher lists on this URL:
- https://curl.haxx.se/docs/ssl-ciphers.html
+ https://curl.se/docs/ssl-ciphers.html
This option is currently used only when curl is built to use OpenSSL 1.1.1 or
later. If you are using a different SSL backend you can try setting TLS 1.3
diff --git a/docs/libcurl/opts/GNURLOPT_TLSAUTH_PASSWORD.3 b/docs/libcurl/opts/GNURLOPT_TLSAUTH_PASSWORD.3
index 7e67d3ee3..153d991ad 100644
--- a/docs/libcurl/opts/GNURLOPT_TLSAUTH_PASSWORD.3
+++ b/docs/libcurl/opts/GNURLOPT_TLSAUTH_PASSWORD.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_TLSAUTH_TYPE.3 b/docs/libcurl/opts/GNURLOPT_TLSAUTH_TYPE.3
index 408c7569e..ee624d2c4 100644
--- a/docs/libcurl/opts/GNURLOPT_TLSAUTH_TYPE.3
+++ b/docs/libcurl/opts/GNURLOPT_TLSAUTH_TYPE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_TLSAUTH_USERNAME.3 b/docs/libcurl/opts/GNURLOPT_TLSAUTH_USERNAME.3
index 1cf8d446e..29c7b9963 100644
--- a/docs/libcurl/opts/GNURLOPT_TLSAUTH_USERNAME.3
+++ b/docs/libcurl/opts/GNURLOPT_TLSAUTH_USERNAME.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_TRAILERDATA.3 b/docs/libcurl/opts/GNURLOPT_TRAILERDATA.3
index 909f051f4..36eb8e6dc 100644
--- a/docs/libcurl/opts/GNURLOPT_TRAILERDATA.3
+++ b/docs/libcurl/opts/GNURLOPT_TRAILERDATA.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_TRAILERFUNCTION.3 b/docs/libcurl/opts/GNURLOPT_TRAILERFUNCTION.3
index a6c3cdd49..da870a857 100644
--- a/docs/libcurl/opts/GNURLOPT_TRAILERFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_TRAILERFUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -73,7 +73,7 @@ static int trailer_cb(struct curl_slist **tr, void *data)
CURL *curl = curl_easy_init();
if(curl) {
/* Set the URL of the request */
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
/* Now set it as a put */
curl_easy_setopt(curl, CURLOPT_PUT, 1L);
@@ -82,7 +82,7 @@ if(curl) {
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_cb);
struct curl_slist *headers = NULL;
- headers = curl_slist_append(headers, "Trailer: My-super-awsome-trailer");
+ headers = curl_slist_append(headers, "Trailer: My-super-awesome-trailer");
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
/* Set the trailers filling callback */
diff --git a/docs/libcurl/opts/GNURLOPT_TRANSFERTEXT.3 b/docs/libcurl/opts/GNURLOPT_TRANSFERTEXT.3
index 0bb4dea5f..68dfd0cd7 100644
--- a/docs/libcurl/opts/GNURLOPT_TRANSFERTEXT.3
+++ b/docs/libcurl/opts/GNURLOPT_TRANSFERTEXT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_TRANSFER_ENCODING.3 b/docs/libcurl/opts/GNURLOPT_TRANSFER_ENCODING.3
index f5f304d6a..8a54f088f 100644
--- a/docs/libcurl/opts/GNURLOPT_TRANSFER_ENCODING.3
+++ b/docs/libcurl/opts/GNURLOPT_TRANSFER_ENCODING.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -48,7 +48,7 @@ HTTP
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_setopt(curl, CURLOPT_TRANSFER_ENCODING, 1L);
curl_easy_perform(curl);
}
diff --git a/docs/libcurl/opts/GNURLOPT_UNIX_SOCKET_PATH.3 b/docs/libcurl/opts/GNURLOPT_UNIX_SOCKET_PATH.3
index 355cf576e..3fb3b218d 100644
--- a/docs/libcurl/opts/GNURLOPT_UNIX_SOCKET_PATH.3
+++ b/docs/libcurl/opts/GNURLOPT_UNIX_SOCKET_PATH.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_UNRESTRICTED_AUTH.3 b/docs/libcurl/opts/GNURLOPT_UNRESTRICTED_AUTH.3
index d10940137..3877e8573 100644
--- a/docs/libcurl/opts/GNURLOPT_UNRESTRICTED_AUTH.3
+++ b/docs/libcurl/opts/GNURLOPT_UNRESTRICTED_AUTH.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -46,7 +46,7 @@ HTTP
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_UNRESTRICTED_AUTH, 1L);
curl_easy_perform(curl);
diff --git a/docs/libcurl/opts/GNURLOPT_UPKEEP_INTERVAL_MS.3 b/docs/libcurl/opts/GNURLOPT_UPKEEP_INTERVAL_MS.3
index 339f2c632..d4f7c8c2e 100644
--- a/docs/libcurl/opts/GNURLOPT_UPKEEP_INTERVAL_MS.3
+++ b/docs/libcurl/opts/GNURLOPT_UPKEEP_INTERVAL_MS.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_UPLOAD.3 b/docs/libcurl/opts/GNURLOPT_UPLOAD.3
index 970b1281c..840cf2dec 100644
--- a/docs/libcurl/opts/GNURLOPT_UPLOAD.3
+++ b/docs/libcurl/opts/GNURLOPT_UPLOAD.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_UPLOAD_BUFFERSIZE.3 b/docs/libcurl/opts/GNURLOPT_UPLOAD_BUFFERSIZE.3
index 9cc3f6cac..a974f3c89 100644
--- a/docs/libcurl/opts/GNURLOPT_UPLOAD_BUFFERSIZE.3
+++ b/docs/libcurl/opts/GNURLOPT_UPLOAD_BUFFERSIZE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_URL.3 b/docs/libcurl/opts/GNURLOPT_URL.3
index 580438d3a..053adaefe 100644
--- a/docs/libcurl/opts/GNURLOPT_URL.3
+++ b/docs/libcurl/opts/GNURLOPT_URL.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -220,8 +220,8 @@ For more information about the individual components of an IMAP URL please
see RFC5092.
.IP SCP
-The path part of a SCP request specifies the file to retrieve and from what
-directory. The file part may not be omitted. The file is taken as an absolute
+The path part of an SCP URL specifies the path and file to retrieve or
+upload. The file part may not be omitted. The file is taken as an absolute
path from the root directory on the server. To specify a path relative to the
user's home directory on the server, prepend ~/ to the path portion. If the
user name is not embedded in the URL, it can be set with the
@@ -232,13 +232,12 @@ scp://user@example.com/etc/issue - This specifies the file /etc/issue
scp://example.com/~/my-file - This specifies the file my-file in the
user's home directory on the server
.IP SFTP
-The path part of a SFTP request specifies the file to retrieve and from what
-directory. If the file part is omitted then libcurl downloads the directory
-listing for the directory specified. If the path ends in a / then a directory
-listing is returned instead of a file. If the path is omitted entirely then
-the directory listing for the root / home directory will be returned. If the
-user name is not embedded in the URL, it can be set with the
-\fICURLOPT_USERPWD(3)\fP or \fICURLOPT_USERNAME(3)\fP option.
+The path part of an SFTP URL specifies the file to retrieve or upload. If the
+path ends in a / then a directory listing is returned instead of a file. If
+the path is omitted entirely then the directory listing for the root / home
+directory will be returned. If the user name is not embedded in the URL, it
+can be set with the \fICURLOPT_USERPWD(3)\fP or \fICURLOPT_USERNAME(3)\fP
+option.
sftp://user:password@example.com/etc/issue - This specifies the file
/etc/issue
@@ -339,7 +338,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_perform(curl);
}
diff --git a/docs/libcurl/opts/GNURLOPT_USERAGENT.3 b/docs/libcurl/opts/GNURLOPT_USERAGENT.3
index 5b28bb322..13777f309 100644
--- a/docs/libcurl/opts/GNURLOPT_USERAGENT.3
+++ b/docs/libcurl/opts/GNURLOPT_USERAGENT.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -43,7 +43,7 @@ HTTP, HTTPS
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_setopt(curl, CURLOPT_USERAGENT, "Dark Secret Ninja/1.0");
diff --git a/docs/libcurl/opts/GNURLOPT_USERNAME.3 b/docs/libcurl/opts/GNURLOPT_USERNAME.3
index b4f36423c..b79f9eccb 100644
--- a/docs/libcurl/opts/GNURLOPT_USERNAME.3
+++ b/docs/libcurl/opts/GNURLOPT_USERNAME.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -66,7 +66,7 @@ Most
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
curl_easy_setopt(curl, CURLOPT_USERNAME, "clark");
diff --git a/docs/libcurl/opts/GNURLOPT_USERPWD.3 b/docs/libcurl/opts/GNURLOPT_USERPWD.3
index 0fd4d394f..c8f95329b 100644
--- a/docs/libcurl/opts/GNURLOPT_USERPWD.3
+++ b/docs/libcurl/opts/GNURLOPT_USERPWD.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -72,7 +72,7 @@ Most
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/foo.bin");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/foo.bin");
curl_easy_setopt(curl, CURLOPT_USERPWD, "clark:kent");
diff --git a/docs/libcurl/opts/GNURLOPT_USE_SSL.3 b/docs/libcurl/opts/GNURLOPT_USE_SSL.3
index ee1f1c7e2..b39e6f53b 100644
--- a/docs/libcurl/opts/GNURLOPT_USE_SSL.3
+++ b/docs/libcurl/opts/GNURLOPT_USE_SSL.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/GNURLOPT_VERBOSE.3 b/docs/libcurl/opts/GNURLOPT_VERBOSE.3
index c2d6523c4..e490be032 100644
--- a/docs/libcurl/opts/GNURLOPT_VERBOSE.3
+++ b/docs/libcurl/opts/GNURLOPT_VERBOSE.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -46,7 +46,7 @@ All
.nf
CURL *curl = curl_easy_init();
if(curl) {
- curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
/* ask libcurl to show us the verbose output */
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
diff --git a/docs/libcurl/opts/GNURLOPT_WILDCARDMATCH.3 b/docs/libcurl/opts/GNURLOPT_WILDCARDMATCH.3
index 8f15cd29d..2ec166de8 100644
--- a/docs/libcurl/opts/GNURLOPT_WILDCARDMATCH.3
+++ b/docs/libcurl/opts/GNURLOPT_WILDCARDMATCH.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -78,7 +78,7 @@ Using the rules above, a file name pattern can be constructed:
.SH PROTOCOLS
This feature is only supported for FTP download.
.SH EXAMPLE
-See https://curl.haxx.se/libcurl/c/ftp-wildcard.html
+See https://curl.se/libcurl/c/ftp-wildcard.html
.SH AVAILABILITY
Added in 7.21.0
.SH RETURN VALUE
diff --git a/docs/libcurl/opts/GNURLOPT_WRITEDATA.3 b/docs/libcurl/opts/GNURLOPT_WRITEDATA.3
index f875f40ee..55c69a0f5 100644
--- a/docs/libcurl/opts/GNURLOPT_WRITEDATA.3
+++ b/docs/libcurl/opts/GNURLOPT_WRITEDATA.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -49,7 +49,7 @@ A common technique is to use the write callback to store the incoming data
into a dynamically growing allocated buffer, and then this
\fICURLOPT_WRITEDATA(3)\fP is used to point to a struct or the buffer to store
data in. Like in the getinmemory example:
-https://curl.haxx.se/libcurl/c/getinmemory.html
+https://curl.se/libcurl/c/getinmemory.html
.SH AVAILABILITY
Available in all libcurl versions. This option was formerly known as
\fICURLOPT_FILE\fP, the name \fICURLOPT_WRITEDATA(3)\fP was introduced in
diff --git a/docs/libcurl/opts/GNURLOPT_WRITEFUNCTION.3 b/docs/libcurl/opts/GNURLOPT_WRITEFUNCTION.3
index ba10cde52..48e7330e4 100644
--- a/docs/libcurl/opts/GNURLOPT_WRITEFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_WRITEFUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -67,6 +67,9 @@ transfer to become paused. See \fIcurl_easy_pause(3)\fP for further details.
Set this option to NULL to get the internal default function used instead of
your callback. The internal default function will write the data to the FILE *
given with \fICURLOPT_WRITEDATA(3)\fP.
+
+This option doesn't enable HSTS, you need to use \fICURLOPT_HSTS_CTRL(3)\fP to
+do that.
.SH DEFAULT
libcurl will use 'fwrite' as a callback by default.
.SH PROTOCOLS
@@ -76,7 +79,7 @@ Support for the CURL_WRITEFUNC_PAUSE return code was added in version 7.18.0.
.SH RETURN VALUE
This will return CURLE_OK.
.SH EXAMPLE
-.NF
+.nf
struct memory {
char *response;
size_t size;
@@ -106,7 +109,7 @@ This will return CURLE_OK.
/* we pass our 'chunk' struct to the callback function */
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
-.FI
+.fi
.SH "SEE ALSO"
.BR CURLOPT_WRITEDATA "(3), " CURLOPT_READFUNCTION "(3), "
.BR CURLOPT_HEADERFUNCTION "(3), "
diff --git a/docs/libcurl/opts/GNURLOPT_XFERINFODATA.3 b/docs/libcurl/opts/GNURLOPT_XFERINFODATA.3
index e09b9599d..f27e944cd 100644
--- a/docs/libcurl/opts/GNURLOPT_XFERINFODATA.3
+++ b/docs/libcurl/opts/GNURLOPT_XFERINFODATA.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -37,7 +37,7 @@ The default value of this parameter is NULL.
.SH PROTOCOLS
All
.SH EXAMPLE
-https://curl.haxx.se/libcurl/c/progressfunc.html
+https://curl.se/libcurl/c/progressfunc.html
.SH AVAILABILITY
Added in 7.32.0
.SH RETURN VALUE
diff --git a/docs/libcurl/opts/GNURLOPT_XFERINFOFUNCTION.3 b/docs/libcurl/opts/GNURLOPT_XFERINFOFUNCTION.3
index 777732b21..99cf02d50 100644
--- a/docs/libcurl/opts/GNURLOPT_XFERINFOFUNCTION.3
+++ b/docs/libcurl/opts/GNURLOPT_XFERINFOFUNCTION.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -75,7 +75,7 @@ users.
.SH PROTOCOLS
All
.SH EXAMPLE
-https://curl.haxx.se/libcurl/c/progressfunc.html
+https://curl.se/libcurl/c/progressfunc.html
.SH AVAILABILITY
Added in 7.32.0. This callback replaces \fICURLOPT_PROGRESSFUNCTION(3)\fP
.SH RETURN VALUE
diff --git a/docs/libcurl/opts/GNURLOPT_XOAUTH2_BEARER.3 b/docs/libcurl/opts/GNURLOPT_XOAUTH2_BEARER.3
index d77dfa167..8f0b3a7fd 100644
--- a/docs/libcurl/opts/GNURLOPT_XOAUTH2_BEARER.3
+++ b/docs/libcurl/opts/GNURLOPT_XOAUTH2_BEARER.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/Makefile.am b/docs/libcurl/opts/Makefile.am
index 35fd619fc..7ebcc6480 100644
--- a/docs/libcurl/opts/Makefile.am
+++ b/docs/libcurl/opts/Makefile.am
@@ -5,11 +5,11 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/opts/Makefile.inc b/docs/libcurl/opts/Makefile.inc
index 6950b718b..dc6b99aca 100644
--- a/docs/libcurl/opts/Makefile.inc
+++ b/docs/libcurl/opts/Makefile.inc
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -22,362 +22,370 @@
# Shared between Makefile.am and CMakeLists.txt
man_MANS = \
- GNURLINFO_ACTIVESOCKET.3 \
- GNURLINFO_APPCONNECT_TIME.3 \
- GNURLINFO_APPCONNECT_TIME_T.3 \
- GNURLINFO_CERTINFO.3 \
- GNURLINFO_CONDITION_UNMET.3 \
- GNURLINFO_CONNECT_TIME.3 \
- GNURLINFO_CONNECT_TIME_T.3 \
- GNURLINFO_CONTENT_LENGTH_DOWNLOAD.3 \
- GNURLINFO_CONTENT_LENGTH_DOWNLOAD_T.3 \
- GNURLINFO_CONTENT_LENGTH_UPLOAD.3 \
- GNURLINFO_CONTENT_LENGTH_UPLOAD_T.3 \
- GNURLINFO_CONTENT_TYPE.3 \
- GNURLINFO_COOKIELIST.3 \
- GNURLINFO_EFFECTIVE_METHOD.3 \
- GNURLINFO_EFFECTIVE_URL.3 \
- GNURLINFO_FILETIME.3 \
- GNURLINFO_FILETIME_T.3 \
- GNURLINFO_FTP_ENTRY_PATH.3 \
- GNURLINFO_HEADER_SIZE.3 \
- GNURLINFO_HTTPAUTH_AVAIL.3 \
- GNURLINFO_HTTP_CONNECTCODE.3 \
- GNURLINFO_HTTP_VERSION.3 \
- GNURLINFO_LASTSOCKET.3 \
- GNURLINFO_LOCAL_IP.3 \
- GNURLINFO_LOCAL_PORT.3 \
- GNURLINFO_NAMELOOKUP_TIME.3 \
- GNURLINFO_NAMELOOKUP_TIME_T.3 \
- GNURLINFO_NUM_CONNECTS.3 \
- GNURLINFO_OS_ERRNO.3 \
- GNURLINFO_PRETRANSFER_TIME.3 \
- GNURLINFO_PRETRANSFER_TIME_T.3 \
- GNURLINFO_PRIMARY_IP.3 \
- GNURLINFO_PRIMARY_PORT.3 \
- GNURLINFO_PRIVATE.3 \
- GNURLINFO_PROTOCOL.3 \
- GNURLINFO_PROXYAUTH_AVAIL.3 \
- GNURLINFO_PROXY_SSL_VERIFYRESULT.3 \
- GNURLINFO_REDIRECT_COUNT.3 \
- GNURLINFO_REDIRECT_TIME.3 \
- GNURLINFO_REDIRECT_TIME_T.3 \
- GNURLINFO_REDIRECT_URL.3 \
- GNURLINFO_REQUEST_SIZE.3 \
- GNURLINFO_RESPONSE_CODE.3 \
- GNURLINFO_RETRY_AFTER.3 \
- GNURLINFO_RTSP_CLIENT_CSEQ.3 \
- GNURLINFO_RTSP_CSEQ_RECV.3 \
- GNURLINFO_RTSP_SERVER_CSEQ.3 \
- GNURLINFO_RTSP_SESSION_ID.3 \
- GNURLINFO_SCHEME.3 \
- GNURLINFO_SIZE_DOWNLOAD.3 \
- GNURLINFO_SIZE_DOWNLOAD_T.3 \
- GNURLINFO_SIZE_UPLOAD.3 \
- GNURLINFO_SIZE_UPLOAD_T.3 \
- GNURLINFO_SPEED_DOWNLOAD.3 \
- GNURLINFO_SPEED_DOWNLOAD_T.3 \
- GNURLINFO_SPEED_UPLOAD.3 \
- GNURLINFO_SPEED_UPLOAD_T.3 \
- GNURLINFO_SSL_ENGINES.3 \
- GNURLINFO_SSL_VERIFYRESULT.3 \
- GNURLINFO_STARTTRANSFER_TIME.3 \
- GNURLINFO_STARTTRANSFER_TIME_T.3 \
- GNURLINFO_TLS_SESSION.3 \
- GNURLINFO_TLS_SSL_PTR.3 \
- GNURLINFO_TOTAL_TIME.3 \
- GNURLINFO_TOTAL_TIME_T.3 \
- GNURLMOPT_CHUNK_LENGTH_PENALTY_SIZE.3 \
- GNURLMOPT_CONTENT_LENGTH_PENALTY_SIZE.3 \
- GNURLMOPT_MAXCONNECTS.3 \
- GNURLMOPT_MAX_CONCURRENT_STREAMS.3 \
- GNURLMOPT_MAX_HOST_CONNECTIONS.3 \
- GNURLMOPT_MAX_PIPELINE_LENGTH.3 \
- GNURLMOPT_MAX_TOTAL_CONNECTIONS.3 \
- GNURLMOPT_PIPELINING.3 \
- GNURLMOPT_PIPELINING_SERVER_BL.3 \
- GNURLMOPT_PIPELINING_SITE_BL.3 \
- GNURLMOPT_PUSHDATA.3 \
- GNURLMOPT_PUSHFUNCTION.3 \
- GNURLMOPT_SOCKETDATA.3 \
- GNURLMOPT_SOCKETFUNCTION.3 \
- GNURLMOPT_TIMERDATA.3 \
- GNURLMOPT_TIMERFUNCTION.3 \
- GNURLOPT_ABSTRACT_UNIX_SOCKET.3 \
- GNURLOPT_ACCEPTTIMEOUT_MS.3 \
- GNURLOPT_ACCEPT_ENCODING.3 \
- GNURLOPT_ADDRESS_SCOPE.3 \
- GNURLOPT_ALTSVC.3 \
- GNURLOPT_ALTSVC_CTRL.3 \
- GNURLOPT_APPEND.3 \
- GNURLOPT_AUTOREFERER.3 \
- GNURLOPT_BUFFERSIZE.3 \
- GNURLOPT_CAINFO.3 \
- GNURLOPT_CAPATH.3 \
- GNURLOPT_CERTINFO.3 \
- GNURLOPT_CHUNK_BGN_FUNCTION.3 \
- GNURLOPT_CHUNK_DATA.3 \
- GNURLOPT_CHUNK_END_FUNCTION.3 \
- GNURLOPT_CLOSESOCKETDATA.3 \
- GNURLOPT_CLOSESOCKETFUNCTION.3 \
- GNURLOPT_CONNECTTIMEOUT.3 \
- GNURLOPT_CONNECTTIMEOUT_MS.3 \
- GNURLOPT_CONNECT_ONLY.3 \
- GNURLOPT_CONNECT_TO.3 \
- GNURLOPT_CONV_FROM_NETWORK_FUNCTION.3 \
- GNURLOPT_CONV_FROM_UTF8_FUNCTION.3 \
- GNURLOPT_CONV_TO_NETWORK_FUNCTION.3 \
- GNURLOPT_COOKIE.3 \
- GNURLOPT_COOKIEFILE.3 \
- GNURLOPT_COOKIEJAR.3 \
- GNURLOPT_COOKIELIST.3 \
- GNURLOPT_COOKIESESSION.3 \
- GNURLOPT_COPYPOSTFIELDS.3 \
- GNURLOPT_CRLF.3 \
- GNURLOPT_CRLFILE.3 \
- GNURLOPT_CURLU.3 \
- GNURLOPT_CUSTOMREQUEST.3 \
- GNURLOPT_DEBUGDATA.3 \
- GNURLOPT_DEBUGFUNCTION.3 \
- GNURLOPT_DEFAULT_PROTOCOL.3 \
- GNURLOPT_DIRLISTONLY.3 \
- GNURLOPT_DISALLOW_USERNAME_IN_URL.3 \
- GNURLOPT_DNS_CACHE_TIMEOUT.3 \
- GNURLOPT_DNS_INTERFACE.3 \
- GNURLOPT_DNS_LOCAL_IP4.3 \
- GNURLOPT_DNS_LOCAL_IP6.3 \
- GNURLOPT_DNS_SERVERS.3 \
- GNURLOPT_DNS_SHUFFLE_ADDRESSES.3 \
- GNURLOPT_DNS_USE_GLOBAL_CACHE.3 \
- GNURLOPT_DOH_URL.3 \
- GNURLOPT_EGDSOCKET.3 \
- GNURLOPT_ERRORBUFFER.3 \
- GNURLOPT_EXPECT_100_TIMEOUT_MS.3 \
- GNURLOPT_FAILONERROR.3 \
- GNURLOPT_FILETIME.3 \
- GNURLOPT_FNMATCH_DATA.3 \
- GNURLOPT_FNMATCH_FUNCTION.3 \
- GNURLOPT_FOLLOWLOCATION.3 \
- GNURLOPT_FORBID_REUSE.3 \
- GNURLOPT_FRESH_CONNECT.3 \
- GNURLOPT_FTPPORT.3 \
- GNURLOPT_FTPSSLAUTH.3 \
- GNURLOPT_FTP_ACCOUNT.3 \
- GNURLOPT_FTP_ALTERNATIVE_TO_USER.3 \
- GNURLOPT_FTP_CREATE_MISSING_DIRS.3 \
- GNURLOPT_FTP_FILEMETHOD.3 \
- GNURLOPT_FTP_RESPONSE_TIMEOUT.3 \
- GNURLOPT_FTP_SKIP_PASV_IP.3 \
- GNURLOPT_FTP_SSL_CCC.3 \
- GNURLOPT_FTP_USE_EPRT.3 \
- GNURLOPT_FTP_USE_EPSV.3 \
- GNURLOPT_FTP_USE_PRET.3 \
- GNURLOPT_GSSAPI_DELEGATION.3 \
- GNURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 \
- GNURLOPT_HAPROXYPROTOCOL.3 \
- GNURLOPT_HEADER.3 \
- GNURLOPT_HEADERDATA.3 \
- GNURLOPT_HEADERFUNCTION.3 \
- GNURLOPT_HEADEROPT.3 \
- GNURLOPT_HTTP09_ALLOWED.3 \
- GNURLOPT_HTTP200ALIASES.3 \
- GNURLOPT_HTTPAUTH.3 \
- GNURLOPT_HTTPGET.3 \
- GNURLOPT_HTTPHEADER.3 \
- GNURLOPT_HTTPPOST.3 \
- GNURLOPT_HTTPPROXYTUNNEL.3 \
- GNURLOPT_HTTP_CONTENT_DECODING.3 \
- GNURLOPT_HTTP_TRANSFER_DECODING.3 \
- GNURLOPT_HTTP_VERSION.3 \
- GNURLOPT_IGNORE_CONTENT_LENGTH.3 \
- GNURLOPT_INFILESIZE.3 \
- GNURLOPT_INFILESIZE_LARGE.3 \
- GNURLOPT_INTERFACE.3 \
- GNURLOPT_INTERLEAVEDATA.3 \
- GNURLOPT_INTERLEAVEFUNCTION.3 \
- GNURLOPT_IOCTLDATA.3 \
- GNURLOPT_IOCTLFUNCTION.3 \
- GNURLOPT_IPRESOLVE.3 \
- GNURLOPT_ISSUERCERT.3 \
- GNURLOPT_ISSUERCERT_BLOB.3 \
- GNURLOPT_KEEP_SENDING_ON_ERROR.3 \
- GNURLOPT_KEYPASSWD.3 \
- GNURLOPT_KRBLEVEL.3 \
- GNURLOPT_LOCALPORT.3 \
- GNURLOPT_LOCALPORTRANGE.3 \
- GNURLOPT_LOGIN_OPTIONS.3 \
- GNURLOPT_LOW_SPEED_LIMIT.3 \
- GNURLOPT_LOW_SPEED_TIME.3 \
- GNURLOPT_MAIL_AUTH.3 \
- GNURLOPT_MAIL_FROM.3 \
- GNURLOPT_MAIL_RCPT.3 \
- GNURLOPT_MAIL_RCPT_ALLLOWFAILS.3 \
- GNURLOPT_MAXAGE_CONN.3 \
- GNURLOPT_MAXCONNECTS.3 \
- GNURLOPT_MAXFILESIZE.3 \
- GNURLOPT_MAXFILESIZE_LARGE.3 \
- GNURLOPT_MAXREDIRS.3 \
- GNURLOPT_MAX_RECV_SPEED_LARGE.3 \
- GNURLOPT_MAX_SEND_SPEED_LARGE.3 \
- GNURLOPT_MIMEPOST.3 \
- GNURLOPT_NETRC.3 \
- GNURLOPT_NETRC_FILE.3 \
- GNURLOPT_NEW_DIRECTORY_PERMS.3 \
- GNURLOPT_NEW_FILE_PERMS.3 \
- GNURLOPT_NOBODY.3 \
- GNURLOPT_NOPROGRESS.3 \
- GNURLOPT_NOPROXY.3 \
- GNURLOPT_NOSIGNAL.3 \
- GNURLOPT_OPENSOCKETDATA.3 \
- GNURLOPT_OPENSOCKETFUNCTION.3 \
- GNURLOPT_PASSWORD.3 \
- GNURLOPT_PATH_AS_IS.3 \
- GNURLOPT_PINNEDPUBLICKEY.3 \
- GNURLOPT_PIPEWAIT.3 \
- GNURLOPT_PORT.3 \
- GNURLOPT_POST.3 \
- GNURLOPT_POSTFIELDS.3 \
- GNURLOPT_POSTFIELDSIZE.3 \
- GNURLOPT_POSTFIELDSIZE_LARGE.3 \
- GNURLOPT_POSTQUOTE.3 \
- GNURLOPT_POSTREDIR.3 \
- GNURLOPT_PREQUOTE.3 \
- GNURLOPT_PRE_PROXY.3 \
- GNURLOPT_PRIVATE.3 \
- GNURLOPT_PROGRESSDATA.3 \
- GNURLOPT_PROGRESSFUNCTION.3 \
- GNURLOPT_PROTOCOLS.3 \
- GNURLOPT_PROXY.3 \
- GNURLOPT_PROXYAUTH.3 \
- GNURLOPT_PROXYHEADER.3 \
- GNURLOPT_PROXYPASSWORD.3 \
- GNURLOPT_PROXYPORT.3 \
- GNURLOPT_PROXYTYPE.3 \
- GNURLOPT_PROXYUSERNAME.3 \
- GNURLOPT_PROXYUSERPWD.3 \
- GNURLOPT_PROXY_CAINFO.3 \
- GNURLOPT_PROXY_CAPATH.3 \
- GNURLOPT_PROXY_CRLFILE.3 \
- GNURLOPT_PROXY_KEYPASSWD.3 \
- GNURLOPT_PROXY_ISSUERCERT.3 \
- GNURLOPT_PROXY_ISSUERCERT_BLOB.3 \
- GNURLOPT_PROXY_PINNEDPUBLICKEY.3 \
- GNURLOPT_PROXY_SERVICE_NAME.3 \
- GNURLOPT_PROXY_SSLCERT.3 \
- GNURLOPT_PROXY_SSLCERT_BLOB.3 \
- GNURLOPT_PROXY_SSLCERTTYPE.3 \
- GNURLOPT_PROXY_SSLKEY.3 \
- GNURLOPT_PROXY_SSLKEY_BLOB.3 \
- GNURLOPT_PROXY_SSLKEYTYPE.3 \
- GNURLOPT_PROXY_SSLVERSION.3 \
- GNURLOPT_PROXY_SSL_CIPHER_LIST.3 \
- GNURLOPT_PROXY_SSL_OPTIONS.3 \
- GNURLOPT_PROXY_SSL_VERIFYHOST.3 \
- GNURLOPT_PROXY_SSL_VERIFYPEER.3 \
- GNURLOPT_PROXY_TLS13_CIPHERS.3 \
- GNURLOPT_PROXY_TLSAUTH_PASSWORD.3 \
- GNURLOPT_PROXY_TLSAUTH_TYPE.3 \
- GNURLOPT_PROXY_TLSAUTH_USERNAME.3 \
- GNURLOPT_PROXY_TRANSFER_MODE.3 \
- GNURLOPT_PUT.3 \
- GNURLOPT_QUOTE.3 \
- GNURLOPT_RANDOM_FILE.3 \
- GNURLOPT_RANGE.3 \
- GNURLOPT_READDATA.3 \
- GNURLOPT_READFUNCTION.3 \
- GNURLOPT_REDIR_PROTOCOLS.3 \
- GNURLOPT_REFERER.3 \
- GNURLOPT_REQUEST_TARGET.3 \
- GNURLOPT_RESOLVE.3 \
- GNURLOPT_RESOLVER_START_DATA.3 \
- GNURLOPT_RESOLVER_START_FUNCTION.3 \
- GNURLOPT_RESUME_FROM.3 \
- GNURLOPT_RESUME_FROM_LARGE.3 \
- GNURLOPT_RTSP_CLIENT_CSEQ.3 \
- GNURLOPT_RTSP_REQUEST.3 \
- GNURLOPT_RTSP_SERVER_CSEQ.3 \
- GNURLOPT_RTSP_SESSION_ID.3 \
- GNURLOPT_RTSP_STREAM_URI.3 \
- GNURLOPT_RTSP_TRANSPORT.3 \
- GNURLOPT_SASL_AUTHZID.3 \
- GNURLOPT_SASL_IR.3 \
- GNURLOPT_SEEKDATA.3 \
- GNURLOPT_SEEKFUNCTION.3 \
- GNURLOPT_SERVICE_NAME.3 \
- GNURLOPT_SHARE.3 \
- GNURLOPT_SOCKOPTDATA.3 \
- GNURLOPT_SOCKOPTFUNCTION.3 \
- GNURLOPT_SOCKS5_AUTH.3 \
- GNURLOPT_SOCKS5_GSSAPI_NEC.3 \
- GNURLOPT_SOCKS5_GSSAPI_SERVICE.3 \
- GNURLOPT_SSH_AUTH_TYPES.3 \
- GNURLOPT_SSH_COMPRESSION.3 \
- GNURLOPT_SSH_HOST_PUBLIC_KEY_MD5.3 \
- GNURLOPT_SSH_KEYDATA.3 \
- GNURLOPT_SSH_KEYFUNCTION.3 \
- GNURLOPT_SSH_KNOWNHOSTS.3 \
- GNURLOPT_SSH_PRIVATE_KEYFILE.3 \
- GNURLOPT_SSH_PUBLIC_KEYFILE.3 \
- GNURLOPT_SSLCERT.3 \
- GNURLOPT_SSLCERT_BLOB.3 \
- GNURLOPT_SSLCERTTYPE.3 \
- GNURLOPT_SSLENGINE.3 \
- GNURLOPT_SSLENGINE_DEFAULT.3 \
- GNURLOPT_SSLKEY.3 \
- GNURLOPT_SSLKEY_BLOB.3 \
- GNURLOPT_SSLKEYTYPE.3 \
- GNURLOPT_SSLVERSION.3 \
- GNURLOPT_SSL_CIPHER_LIST.3 \
- GNURLOPT_SSL_CTX_DATA.3 \
- GNURLOPT_SSL_CTX_FUNCTION.3 \
- GNURLOPT_SSL_ENABLE_ALPN.3 \
- GNURLOPT_SSL_ENABLE_NPN.3 \
- GNURLOPT_SSL_FALSESTART.3 \
- GNURLOPT_SSL_OPTIONS.3 \
- GNURLOPT_SSL_SESSIONID_CACHE.3 \
- GNURLOPT_SSL_VERIFYHOST.3 \
- GNURLOPT_SSL_VERIFYPEER.3 \
- GNURLOPT_SSL_VERIFYSTATUS.3 \
- GNURLOPT_STDERR.3 \
- GNURLOPT_STREAM_DEPENDS.3 \
- GNURLOPT_STREAM_DEPENDS_E.3 \
- GNURLOPT_STREAM_WEIGHT.3 \
- GNURLOPT_SUPPRESS_CONNECT_HEADERS.3 \
- GNURLOPT_TCP_FASTOPEN.3 \
- GNURLOPT_TCP_KEEPALIVE.3 \
- GNURLOPT_TCP_KEEPIDLE.3 \
- GNURLOPT_TCP_KEEPINTVL.3 \
- GNURLOPT_TCP_NODELAY.3 \
- GNURLOPT_TELNETOPTIONS.3 \
- GNURLOPT_TFTP_BLKSIZE.3 \
- GNURLOPT_TFTP_NO_OPTIONS.3 \
- GNURLOPT_TIMECONDITION.3 \
- GNURLOPT_TIMEOUT.3 \
- GNURLOPT_TIMEOUT_MS.3 \
- GNURLOPT_TIMEVALUE.3 \
- GNURLOPT_TIMEVALUE_LARGE.3 \
- GNURLOPT_TLS13_CIPHERS.3 \
- GNURLOPT_TLSAUTH_PASSWORD.3 \
- GNURLOPT_TLSAUTH_TYPE.3 \
- GNURLOPT_TLSAUTH_USERNAME.3 \
- GNURLOPT_TRAILERDATA.3 \
- GNURLOPT_TRAILERFUNCTION.3 \
- GNURLOPT_TRANSFERTEXT.3 \
- GNURLOPT_TRANSFER_ENCODING.3 \
- GNURLOPT_UNIX_SOCKET_PATH.3 \
- GNURLOPT_UNRESTRICTED_AUTH.3 \
- GNURLOPT_UPKEEP_INTERVAL_MS.3 \
- GNURLOPT_UPLOAD.3 \
- GNURLOPT_UPLOAD_BUFFERSIZE.3 \
- GNURLOPT_URL.3 \
- GNURLOPT_USERAGENT.3 \
- GNURLOPT_USERNAME.3 \
- GNURLOPT_USERPWD.3 \
- GNURLOPT_USE_SSL.3 \
- GNURLOPT_VERBOSE.3 \
- GNURLOPT_WILDCARDMATCH.3 \
- GNURLOPT_WRITEDATA.3 \
- GNURLOPT_WRITEFUNCTION.3 \
- GNURLOPT_XFERINFODATA.3 \
- GNURLOPT_XFERINFOFUNCTION.3 \
- GNURLOPT_XOAUTH2_BEARER.3
+ CURLINFO_ACTIVESOCKET.3 \
+ CURLINFO_APPCONNECT_TIME.3 \
+ CURLINFO_APPCONNECT_TIME_T.3 \
+ CURLINFO_CERTINFO.3 \
+ CURLINFO_CONDITION_UNMET.3 \
+ CURLINFO_CONNECT_TIME.3 \
+ CURLINFO_CONNECT_TIME_T.3 \
+ CURLINFO_CONTENT_LENGTH_DOWNLOAD.3 \
+ CURLINFO_CONTENT_LENGTH_DOWNLOAD_T.3 \
+ CURLINFO_CONTENT_LENGTH_UPLOAD.3 \
+ CURLINFO_CONTENT_LENGTH_UPLOAD_T.3 \
+ CURLINFO_CONTENT_TYPE.3 \
+ CURLINFO_COOKIELIST.3 \
+ CURLINFO_EFFECTIVE_METHOD.3 \
+ CURLINFO_EFFECTIVE_URL.3 \
+ CURLINFO_FILETIME.3 \
+ CURLINFO_FILETIME_T.3 \
+ CURLINFO_FTP_ENTRY_PATH.3 \
+ CURLINFO_HEADER_SIZE.3 \
+ CURLINFO_HTTPAUTH_AVAIL.3 \
+ CURLINFO_HTTP_CONNECTCODE.3 \
+ CURLINFO_HTTP_VERSION.3 \
+ CURLINFO_LASTSOCKET.3 \
+ CURLINFO_LOCAL_IP.3 \
+ CURLINFO_LOCAL_PORT.3 \
+ CURLINFO_NAMELOOKUP_TIME.3 \
+ CURLINFO_NAMELOOKUP_TIME_T.3 \
+ CURLINFO_NUM_CONNECTS.3 \
+ CURLINFO_OS_ERRNO.3 \
+ CURLINFO_PRETRANSFER_TIME.3 \
+ CURLINFO_PRETRANSFER_TIME_T.3 \
+ CURLINFO_PRIMARY_IP.3 \
+ CURLINFO_PRIMARY_PORT.3 \
+ CURLINFO_PRIVATE.3 \
+ CURLINFO_PROTOCOL.3 \
+ CURLINFO_PROXY_ERROR.3 \
+ CURLINFO_PROXY_SSL_VERIFYRESULT.3 \
+ CURLINFO_PROXYAUTH_AVAIL.3 \
+ CURLINFO_REDIRECT_COUNT.3 \
+ CURLINFO_REDIRECT_TIME.3 \
+ CURLINFO_REDIRECT_TIME_T.3 \
+ CURLINFO_REDIRECT_URL.3 \
+ CURLINFO_REQUEST_SIZE.3 \
+ CURLINFO_RESPONSE_CODE.3 \
+ CURLINFO_RETRY_AFTER.3 \
+ CURLINFO_RTSP_CLIENT_CSEQ.3 \
+ CURLINFO_RTSP_CSEQ_RECV.3 \
+ CURLINFO_RTSP_SERVER_CSEQ.3 \
+ CURLINFO_RTSP_SESSION_ID.3 \
+ CURLINFO_SCHEME.3 \
+ CURLINFO_SIZE_DOWNLOAD.3 \
+ CURLINFO_SIZE_DOWNLOAD_T.3 \
+ CURLINFO_SIZE_UPLOAD.3 \
+ CURLINFO_SIZE_UPLOAD_T.3 \
+ CURLINFO_SPEED_DOWNLOAD.3 \
+ CURLINFO_SPEED_DOWNLOAD_T.3 \
+ CURLINFO_SPEED_UPLOAD.3 \
+ CURLINFO_SPEED_UPLOAD_T.3 \
+ CURLINFO_SSL_ENGINES.3 \
+ CURLINFO_SSL_VERIFYRESULT.3 \
+ CURLINFO_STARTTRANSFER_TIME.3 \
+ CURLINFO_STARTTRANSFER_TIME_T.3 \
+ CURLINFO_TLS_SESSION.3 \
+ CURLINFO_TLS_SSL_PTR.3 \
+ CURLINFO_TOTAL_TIME.3 \
+ CURLINFO_TOTAL_TIME_T.3 \
+ CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE.3 \
+ CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE.3 \
+ CURLMOPT_MAXCONNECTS.3 \
+ CURLMOPT_MAX_CONCURRENT_STREAMS.3 \
+ CURLMOPT_MAX_HOST_CONNECTIONS.3 \
+ CURLMOPT_MAX_PIPELINE_LENGTH.3 \
+ CURLMOPT_MAX_TOTAL_CONNECTIONS.3 \
+ CURLMOPT_PIPELINING.3 \
+ CURLMOPT_PIPELINING_SERVER_BL.3 \
+ CURLMOPT_PIPELINING_SITE_BL.3 \
+ CURLMOPT_PUSHDATA.3 \
+ CURLMOPT_PUSHFUNCTION.3 \
+ CURLMOPT_SOCKETDATA.3 \
+ CURLMOPT_SOCKETFUNCTION.3 \
+ CURLMOPT_TIMERDATA.3 \
+ CURLMOPT_TIMERFUNCTION.3 \
+ CURLOPT_ABSTRACT_UNIX_SOCKET.3 \
+ CURLOPT_ACCEPTTIMEOUT_MS.3 \
+ CURLOPT_ACCEPT_ENCODING.3 \
+ CURLOPT_ADDRESS_SCOPE.3 \
+ CURLOPT_ALTSVC.3 \
+ CURLOPT_ALTSVC_CTRL.3 \
+ CURLOPT_APPEND.3 \
+ CURLOPT_AUTOREFERER.3 \
+ CURLOPT_BUFFERSIZE.3 \
+ CURLOPT_CAINFO.3 \
+ CURLOPT_CAPATH.3 \
+ CURLOPT_CERTINFO.3 \
+ CURLOPT_CHUNK_BGN_FUNCTION.3 \
+ CURLOPT_CHUNK_DATA.3 \
+ CURLOPT_CHUNK_END_FUNCTION.3 \
+ CURLOPT_CLOSESOCKETDATA.3 \
+ CURLOPT_CLOSESOCKETFUNCTION.3 \
+ CURLOPT_CONNECTTIMEOUT.3 \
+ CURLOPT_CONNECTTIMEOUT_MS.3 \
+ CURLOPT_CONNECT_ONLY.3 \
+ CURLOPT_CONNECT_TO.3 \
+ CURLOPT_CONV_FROM_NETWORK_FUNCTION.3 \
+ CURLOPT_CONV_FROM_UTF8_FUNCTION.3 \
+ CURLOPT_CONV_TO_NETWORK_FUNCTION.3 \
+ CURLOPT_COOKIE.3 \
+ CURLOPT_COOKIEFILE.3 \
+ CURLOPT_COOKIEJAR.3 \
+ CURLOPT_COOKIELIST.3 \
+ CURLOPT_COOKIESESSION.3 \
+ CURLOPT_COPYPOSTFIELDS.3 \
+ CURLOPT_CRLF.3 \
+ CURLOPT_CRLFILE.3 \
+ CURLOPT_CURLU.3 \
+ CURLOPT_CUSTOMREQUEST.3 \
+ CURLOPT_DEBUGDATA.3 \
+ CURLOPT_DEBUGFUNCTION.3 \
+ CURLOPT_DEFAULT_PROTOCOL.3 \
+ CURLOPT_DIRLISTONLY.3 \
+ CURLOPT_DISALLOW_USERNAME_IN_URL.3 \
+ CURLOPT_DNS_CACHE_TIMEOUT.3 \
+ CURLOPT_DNS_INTERFACE.3 \
+ CURLOPT_DNS_LOCAL_IP4.3 \
+ CURLOPT_DNS_LOCAL_IP6.3 \
+ CURLOPT_DNS_SERVERS.3 \
+ CURLOPT_DNS_SHUFFLE_ADDRESSES.3 \
+ CURLOPT_DNS_USE_GLOBAL_CACHE.3 \
+ CURLOPT_DOH_URL.3 \
+ CURLOPT_EGDSOCKET.3 \
+ CURLOPT_ERRORBUFFER.3 \
+ CURLOPT_EXPECT_100_TIMEOUT_MS.3 \
+ CURLOPT_FAILONERROR.3 \
+ CURLOPT_FILETIME.3 \
+ CURLOPT_FNMATCH_DATA.3 \
+ CURLOPT_FNMATCH_FUNCTION.3 \
+ CURLOPT_FOLLOWLOCATION.3 \
+ CURLOPT_FORBID_REUSE.3 \
+ CURLOPT_FRESH_CONNECT.3 \
+ CURLOPT_FTPPORT.3 \
+ CURLOPT_FTPSSLAUTH.3 \
+ CURLOPT_FTP_ACCOUNT.3 \
+ CURLOPT_FTP_ALTERNATIVE_TO_USER.3 \
+ CURLOPT_FTP_CREATE_MISSING_DIRS.3 \
+ CURLOPT_FTP_FILEMETHOD.3 \
+ CURLOPT_FTP_RESPONSE_TIMEOUT.3 \
+ CURLOPT_FTP_SKIP_PASV_IP.3 \
+ CURLOPT_FTP_SSL_CCC.3 \
+ CURLOPT_FTP_USE_EPRT.3 \
+ CURLOPT_FTP_USE_EPSV.3 \
+ CURLOPT_FTP_USE_PRET.3 \
+ CURLOPT_GSSAPI_DELEGATION.3 \
+ CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 \
+ CURLOPT_HAPROXYPROTOCOL.3 \
+ CURLOPT_HEADER.3 \
+ CURLOPT_HEADERDATA.3 \
+ CURLOPT_HEADERFUNCTION.3 \
+ CURLOPT_HEADEROPT.3 \
+ CURLOPT_HSTS.3 \
+ CURLOPT_HSTSREADDATA.3 \
+ CURLOPT_HSTSREADFUNCTION.3 \
+ CURLOPT_HSTSWRITEDATA.3 \
+ CURLOPT_HSTSWRITEFUNCTION.3 \
+ CURLOPT_HSTS_CTRL.3 \
+ CURLOPT_HTTP09_ALLOWED.3 \
+ CURLOPT_HTTP200ALIASES.3 \
+ CURLOPT_HTTPAUTH.3 \
+ CURLOPT_HTTPGET.3 \
+ CURLOPT_HTTPHEADER.3 \
+ CURLOPT_HTTPPOST.3 \
+ CURLOPT_HTTPPROXYTUNNEL.3 \
+ CURLOPT_HTTP_CONTENT_DECODING.3 \
+ CURLOPT_HTTP_TRANSFER_DECODING.3 \
+ CURLOPT_HTTP_VERSION.3 \
+ CURLOPT_IGNORE_CONTENT_LENGTH.3 \
+ CURLOPT_INFILESIZE.3 \
+ CURLOPT_INFILESIZE_LARGE.3 \
+ CURLOPT_INTERFACE.3 \
+ CURLOPT_INTERLEAVEDATA.3 \
+ CURLOPT_INTERLEAVEFUNCTION.3 \
+ CURLOPT_IOCTLDATA.3 \
+ CURLOPT_IOCTLFUNCTION.3 \
+ CURLOPT_IPRESOLVE.3 \
+ CURLOPT_ISSUERCERT.3 \
+ CURLOPT_ISSUERCERT_BLOB.3 \
+ CURLOPT_KEEP_SENDING_ON_ERROR.3 \
+ CURLOPT_KEYPASSWD.3 \
+ CURLOPT_KRBLEVEL.3 \
+ CURLOPT_LOCALPORT.3 \
+ CURLOPT_LOCALPORTRANGE.3 \
+ CURLOPT_LOGIN_OPTIONS.3 \
+ CURLOPT_LOW_SPEED_LIMIT.3 \
+ CURLOPT_LOW_SPEED_TIME.3 \
+ CURLOPT_MAIL_AUTH.3 \
+ CURLOPT_MAIL_FROM.3 \
+ CURLOPT_MAIL_RCPT.3 \
+ CURLOPT_MAIL_RCPT_ALLLOWFAILS.3 \
+ CURLOPT_MAXAGE_CONN.3 \
+ CURLOPT_MAXCONNECTS.3 \
+ CURLOPT_MAXFILESIZE.3 \
+ CURLOPT_MAXFILESIZE_LARGE.3 \
+ CURLOPT_MAXREDIRS.3 \
+ CURLOPT_MAX_RECV_SPEED_LARGE.3 \
+ CURLOPT_MAX_SEND_SPEED_LARGE.3 \
+ CURLOPT_MIMEPOST.3 \
+ CURLOPT_NETRC.3 \
+ CURLOPT_NETRC_FILE.3 \
+ CURLOPT_NEW_DIRECTORY_PERMS.3 \
+ CURLOPT_NEW_FILE_PERMS.3 \
+ CURLOPT_NOBODY.3 \
+ CURLOPT_NOPROGRESS.3 \
+ CURLOPT_NOPROXY.3 \
+ CURLOPT_NOSIGNAL.3 \
+ CURLOPT_OPENSOCKETDATA.3 \
+ CURLOPT_OPENSOCKETFUNCTION.3 \
+ CURLOPT_PASSWORD.3 \
+ CURLOPT_PATH_AS_IS.3 \
+ CURLOPT_PINNEDPUBLICKEY.3 \
+ CURLOPT_PIPEWAIT.3 \
+ CURLOPT_PORT.3 \
+ CURLOPT_POST.3 \
+ CURLOPT_POSTFIELDS.3 \
+ CURLOPT_POSTFIELDSIZE.3 \
+ CURLOPT_POSTFIELDSIZE_LARGE.3 \
+ CURLOPT_POSTQUOTE.3 \
+ CURLOPT_POSTREDIR.3 \
+ CURLOPT_PREQUOTE.3 \
+ CURLOPT_PRE_PROXY.3 \
+ CURLOPT_PRIVATE.3 \
+ CURLOPT_PROGRESSDATA.3 \
+ CURLOPT_PROGRESSFUNCTION.3 \
+ CURLOPT_PROTOCOLS.3 \
+ CURLOPT_PROXY.3 \
+ CURLOPT_PROXYAUTH.3 \
+ CURLOPT_PROXYHEADER.3 \
+ CURLOPT_PROXYPASSWORD.3 \
+ CURLOPT_PROXYPORT.3 \
+ CURLOPT_PROXYTYPE.3 \
+ CURLOPT_PROXYUSERNAME.3 \
+ CURLOPT_PROXYUSERPWD.3 \
+ CURLOPT_PROXY_CAINFO.3 \
+ CURLOPT_PROXY_CAPATH.3 \
+ CURLOPT_PROXY_CRLFILE.3 \
+ CURLOPT_PROXY_KEYPASSWD.3 \
+ CURLOPT_PROXY_ISSUERCERT.3 \
+ CURLOPT_PROXY_ISSUERCERT_BLOB.3 \
+ CURLOPT_PROXY_PINNEDPUBLICKEY.3 \
+ CURLOPT_PROXY_SERVICE_NAME.3 \
+ CURLOPT_PROXY_SSLCERT.3 \
+ CURLOPT_PROXY_SSLCERT_BLOB.3 \
+ CURLOPT_PROXY_SSLCERTTYPE.3 \
+ CURLOPT_PROXY_SSLKEY.3 \
+ CURLOPT_PROXY_SSLKEY_BLOB.3 \
+ CURLOPT_PROXY_SSLKEYTYPE.3 \
+ CURLOPT_PROXY_SSLVERSION.3 \
+ CURLOPT_PROXY_SSL_CIPHER_LIST.3 \
+ CURLOPT_PROXY_SSL_OPTIONS.3 \
+ CURLOPT_PROXY_SSL_VERIFYHOST.3 \
+ CURLOPT_PROXY_SSL_VERIFYPEER.3 \
+ CURLOPT_PROXY_TLS13_CIPHERS.3 \
+ CURLOPT_PROXY_TLSAUTH_PASSWORD.3 \
+ CURLOPT_PROXY_TLSAUTH_TYPE.3 \
+ CURLOPT_PROXY_TLSAUTH_USERNAME.3 \
+ CURLOPT_PROXY_TRANSFER_MODE.3 \
+ CURLOPT_PUT.3 \
+ CURLOPT_QUOTE.3 \
+ CURLOPT_RANDOM_FILE.3 \
+ CURLOPT_RANGE.3 \
+ CURLOPT_READDATA.3 \
+ CURLOPT_READFUNCTION.3 \
+ CURLOPT_REDIR_PROTOCOLS.3 \
+ CURLOPT_REFERER.3 \
+ CURLOPT_REQUEST_TARGET.3 \
+ CURLOPT_RESOLVE.3 \
+ CURLOPT_RESOLVER_START_DATA.3 \
+ CURLOPT_RESOLVER_START_FUNCTION.3 \
+ CURLOPT_RESUME_FROM.3 \
+ CURLOPT_RESUME_FROM_LARGE.3 \
+ CURLOPT_RTSP_CLIENT_CSEQ.3 \
+ CURLOPT_RTSP_REQUEST.3 \
+ CURLOPT_RTSP_SERVER_CSEQ.3 \
+ CURLOPT_RTSP_SESSION_ID.3 \
+ CURLOPT_RTSP_STREAM_URI.3 \
+ CURLOPT_RTSP_TRANSPORT.3 \
+ CURLOPT_SASL_AUTHZID.3 \
+ CURLOPT_SASL_IR.3 \
+ CURLOPT_SEEKDATA.3 \
+ CURLOPT_SEEKFUNCTION.3 \
+ CURLOPT_SERVICE_NAME.3 \
+ CURLOPT_SHARE.3 \
+ CURLOPT_SOCKOPTDATA.3 \
+ CURLOPT_SOCKOPTFUNCTION.3 \
+ CURLOPT_SOCKS5_AUTH.3 \
+ CURLOPT_SOCKS5_GSSAPI_NEC.3 \
+ CURLOPT_SOCKS5_GSSAPI_SERVICE.3 \
+ CURLOPT_SSH_AUTH_TYPES.3 \
+ CURLOPT_SSH_COMPRESSION.3 \
+ CURLOPT_SSH_HOST_PUBLIC_KEY_MD5.3 \
+ CURLOPT_SSH_KEYDATA.3 \
+ CURLOPT_SSH_KEYFUNCTION.3 \
+ CURLOPT_SSH_KNOWNHOSTS.3 \
+ CURLOPT_SSH_PRIVATE_KEYFILE.3 \
+ CURLOPT_SSH_PUBLIC_KEYFILE.3 \
+ CURLOPT_SSLCERT.3 \
+ CURLOPT_SSLCERT_BLOB.3 \
+ CURLOPT_SSLCERTTYPE.3 \
+ CURLOPT_SSLENGINE.3 \
+ CURLOPT_SSLENGINE_DEFAULT.3 \
+ CURLOPT_SSLKEY.3 \
+ CURLOPT_SSLKEY_BLOB.3 \
+ CURLOPT_SSLKEYTYPE.3 \
+ CURLOPT_SSLVERSION.3 \
+ CURLOPT_SSL_CIPHER_LIST.3 \
+ CURLOPT_SSL_CTX_DATA.3 \
+ CURLOPT_SSL_CTX_FUNCTION.3 \
+ CURLOPT_SSL_EC_CURVES.3 \
+ CURLOPT_SSL_ENABLE_ALPN.3 \
+ CURLOPT_SSL_ENABLE_NPN.3 \
+ CURLOPT_SSL_FALSESTART.3 \
+ CURLOPT_SSL_OPTIONS.3 \
+ CURLOPT_SSL_SESSIONID_CACHE.3 \
+ CURLOPT_SSL_VERIFYHOST.3 \
+ CURLOPT_SSL_VERIFYPEER.3 \
+ CURLOPT_SSL_VERIFYSTATUS.3 \
+ CURLOPT_STDERR.3 \
+ CURLOPT_STREAM_DEPENDS.3 \
+ CURLOPT_STREAM_DEPENDS_E.3 \
+ CURLOPT_STREAM_WEIGHT.3 \
+ CURLOPT_SUPPRESS_CONNECT_HEADERS.3 \
+ CURLOPT_TCP_FASTOPEN.3 \
+ CURLOPT_TCP_KEEPALIVE.3 \
+ CURLOPT_TCP_KEEPIDLE.3 \
+ CURLOPT_TCP_KEEPINTVL.3 \
+ CURLOPT_TCP_NODELAY.3 \
+ CURLOPT_TELNETOPTIONS.3 \
+ CURLOPT_TFTP_BLKSIZE.3 \
+ CURLOPT_TFTP_NO_OPTIONS.3 \
+ CURLOPT_TIMECONDITION.3 \
+ CURLOPT_TIMEOUT.3 \
+ CURLOPT_TIMEOUT_MS.3 \
+ CURLOPT_TIMEVALUE.3 \
+ CURLOPT_TIMEVALUE_LARGE.3 \
+ CURLOPT_TLS13_CIPHERS.3 \
+ CURLOPT_TLSAUTH_PASSWORD.3 \
+ CURLOPT_TLSAUTH_TYPE.3 \
+ CURLOPT_TLSAUTH_USERNAME.3 \
+ CURLOPT_TRAILERDATA.3 \
+ CURLOPT_TRAILERFUNCTION.3 \
+ CURLOPT_TRANSFERTEXT.3 \
+ CURLOPT_TRANSFER_ENCODING.3 \
+ CURLOPT_UNIX_SOCKET_PATH.3 \
+ CURLOPT_UNRESTRICTED_AUTH.3 \
+ CURLOPT_UPKEEP_INTERVAL_MS.3 \
+ CURLOPT_UPLOAD.3 \
+ CURLOPT_UPLOAD_BUFFERSIZE.3 \
+ CURLOPT_URL.3 \
+ CURLOPT_USERAGENT.3 \
+ CURLOPT_USERNAME.3 \
+ CURLOPT_USERPWD.3 \
+ CURLOPT_USE_SSL.3 \
+ CURLOPT_VERBOSE.3 \
+ CURLOPT_WILDCARDMATCH.3 \
+ CURLOPT_WRITEDATA.3 \
+ CURLOPT_WRITEFUNCTION.3 \
+ CURLOPT_XFERINFODATA.3 \
+ CURLOPT_XFERINFOFUNCTION.3 \
+ CURLOPT_XOAUTH2_BEARER.3
diff --git a/docs/libcurl/opts/template.3 b/docs/libcurl/opts/template.3
index 8ed63bc6d..4115956fc 100644
--- a/docs/libcurl/opts/template.3
+++ b/docs/libcurl/opts/template.3
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
index c0cdbdc04..861aaf88f 100644
--- a/docs/libcurl/symbols-in-versions
+++ b/docs/libcurl/symbols-in-versions
@@ -15,7 +15,6 @@
CURLALTSVC_H1 7.64.1
CURLALTSVC_H2 7.64.1
CURLALTSVC_H3 7.64.1
-CURLALTSVC_IMMEDIATELY 7.64.1
CURLALTSVC_READONLYFILE 7.64.1
CURLAUTH_ANY 7.10.6
CURLAUTH_ANYSAFE 7.10.6
@@ -105,6 +104,7 @@ CURLE_OPERATION_TIMEOUTED 7.1 7.17.0
CURLE_OUT_OF_MEMORY 7.1
CURLE_PARTIAL_FILE 7.1
CURLE_PEER_FAILED_VERIFICATION 7.17.1
+CURLE_PROXY 7.73.0
CURLE_QUIC_CONNECT_ERROR 7.69.0
CURLE_QUOTE_ERROR 7.17.0
CURLE_RANGE_ERROR 7.17.0
@@ -213,6 +213,8 @@ CURLGSSAPI_DELEGATION_NONE 7.22.0
CURLGSSAPI_DELEGATION_POLICY_FLAG 7.22.0
CURLHEADER_SEPARATE 7.37.0
CURLHEADER_UNIFIED 7.37.0
+CURLHSTS_ENABLE 7.74.0
+CURLHSTS_READONLYFILE 7.74.0
CURLINFO_ACTIVESOCKET 7.45.0
CURLINFO_APPCONNECT_TIME 7.19.0
CURLINFO_APPCONNECT_TIME_T 7.61.0
@@ -261,6 +263,7 @@ CURLINFO_PRIMARY_PORT 7.21.0
CURLINFO_PRIVATE 7.10.3
CURLINFO_PROTOCOL 7.52.0
CURLINFO_PROXYAUTH_AVAIL 7.10.8
+CURLINFO_PROXY_ERROR 7.73.0
CURLINFO_PROXY_SSL_VERIFYRESULT 7.52.0
CURLINFO_PTR 7.54.1
CURLINFO_REDIRECT_COUNT 7.9.7
@@ -309,6 +312,7 @@ CURLKHMATCH_OK 7.19.6
CURLKHSTAT_DEFER 7.19.6
CURLKHSTAT_FINE 7.19.6
CURLKHSTAT_FINE_ADD_TO_FILE 7.19.6
+CURLKHSTAT_FINE_REPLACE 7.73.0
CURLKHSTAT_REJECT 7.19.6
CURLKHTYPE_DSS 7.19.6
CURLKHTYPE_ECDSA 7.58.0
@@ -349,12 +353,14 @@ CURLM_UNKNOWN_OPTION 7.15.4
CURLM_WAKEUP_FAILURE 7.68.0
CURLOPT 7.69.0
CURLOPTTYPE_BLOB 7.71.0
+CURLOPTTYPE_CBPOINT 7.73.0
CURLOPTTYPE_FUNCTIONPOINT 7.1
CURLOPTTYPE_LONG 7.1
CURLOPTTYPE_OBJECTPOINT 7.1
CURLOPTTYPE_OFF_T 7.11.0
CURLOPTTYPE_SLISTPOINT 7.65.2
CURLOPTTYPE_STRINGPOINT 7.46.0
+CURLOPTTYPE_VALUES 7.73.0
CURLOPT_ABSTRACT_UNIX_SOCKET 7.53.0
CURLOPT_ACCEPTTIMEOUT_MS 7.24.0
CURLOPT_ACCEPT_ENCODING 7.21.6
@@ -439,6 +445,12 @@ CURLOPT_HEADER 7.1
CURLOPT_HEADERDATA 7.10
CURLOPT_HEADERFUNCTION 7.7.2
CURLOPT_HEADEROPT 7.37.0
+CURLOPT_HSTS 7.74.0
+CURLOPT_HSTS_CTRL 7.74.0
+CURLOPT_HSTSREADDATA 7.74.0
+CURLOPT_HSTSREADFUNCTION 7.74.0
+CURLOPT_HSTSWRITEDATA 7.74.0
+CURLOPT_HSTSWRITEFUNCTION 7.74.0
CURLOPT_HTTP09_ALLOWED 7.64.0
CURLOPT_HTTP200ALIASES 7.10.3
CURLOPT_HTTPAUTH 7.10.6
@@ -517,8 +529,6 @@ CURLOPT_PROGRESSDATA 7.1
CURLOPT_PROGRESSFUNCTION 7.1 7.32.0
CURLOPT_PROTOCOLS 7.19.4
CURLOPT_PROXY 7.1
-CURLOPT_PROXY_ISSUERCERT 7.71.0
-CURLOPT_PROXY_ISSUERCERT_BLOB 7.71.0
CURLOPT_PROXYAUTH 7.10.7
CURLOPT_PROXYHEADER 7.37.0
CURLOPT_PROXYPASSWORD 7.19.1
@@ -529,15 +539,17 @@ CURLOPT_PROXYUSERPWD 7.1
CURLOPT_PROXY_CAINFO 7.52.0
CURLOPT_PROXY_CAPATH 7.52.0
CURLOPT_PROXY_CRLFILE 7.52.0
+CURLOPT_PROXY_ISSUERCERT 7.71.0
+CURLOPT_PROXY_ISSUERCERT_BLOB 7.71.0
CURLOPT_PROXY_KEYPASSWD 7.52.0
CURLOPT_PROXY_PINNEDPUBLICKEY 7.52.0
CURLOPT_PROXY_SERVICE_NAME 7.43.0
CURLOPT_PROXY_SSLCERT 7.52.0
-CURLOPT_PROXY_SSLCERT_BLOB 7.71.0
CURLOPT_PROXY_SSLCERTTYPE 7.52.0
+CURLOPT_PROXY_SSLCERT_BLOB 7.71.0
CURLOPT_PROXY_SSLKEY 7.52.0
-CURLOPT_PROXY_SSLKEY_BLOB 7.71.0
CURLOPT_PROXY_SSLKEYTYPE 7.52.0
+CURLOPT_PROXY_SSLKEY_BLOB 7.71.0
CURLOPT_PROXY_SSLVERSION 7.52.0
CURLOPT_PROXY_SSL_CIPHER_LIST 7.52.0
CURLOPT_PROXY_SSL_OPTIONS 7.52.0
@@ -598,19 +610,20 @@ CURLOPT_SSH_KNOWNHOSTS 7.19.6
CURLOPT_SSH_PRIVATE_KEYFILE 7.16.1
CURLOPT_SSH_PUBLIC_KEYFILE 7.16.1
CURLOPT_SSLCERT 7.1
-CURLOPT_SSLCERT_BLOB 7.71.0
CURLOPT_SSLCERTPASSWD 7.1.1 7.17.0
CURLOPT_SSLCERTTYPE 7.9.3
+CURLOPT_SSLCERT_BLOB 7.71.0
CURLOPT_SSLENGINE 7.9.3
CURLOPT_SSLENGINE_DEFAULT 7.9.3
CURLOPT_SSLKEY 7.9.3
-CURLOPT_SSLKEY_BLOB 7.71.0
CURLOPT_SSLKEYPASSWD 7.9.3 7.17.0
CURLOPT_SSLKEYTYPE 7.9.3
+CURLOPT_SSLKEY_BLOB 7.71.0
CURLOPT_SSLVERSION 7.1
CURLOPT_SSL_CIPHER_LIST 7.9
CURLOPT_SSL_CTX_DATA 7.10.6
CURLOPT_SSL_CTX_FUNCTION 7.10.6
+CURLOPT_SSL_EC_CURVES 7.73.0
CURLOPT_SSL_ENABLE_ALPN 7.36.0
CURLOPT_SSL_ENABLE_NPN 7.36.0
CURLOPT_SSL_FALSESTART 7.42.0
@@ -664,6 +677,15 @@ CURLOPT_WRITEINFO 7.1
CURLOPT_XFERINFODATA 7.32.0
CURLOPT_XFERINFOFUNCTION 7.32.0
CURLOPT_XOAUTH2_BEARER 7.33.0
+CURLOT_BLOB 7.73.0
+CURLOT_CBPTR 7.73.0
+CURLOT_FUNCTION 7.73.0
+CURLOT_LONG 7.73.0
+CURLOT_OBJECT 7.73.0
+CURLOT_OFF_T 7.73.0
+CURLOT_SLIST 7.73.0
+CURLOT_STRING 7.73.0
+CURLOT_VALUES 7.73.0
CURLPAUSE_ALL 7.18.0
CURLPAUSE_CONT 7.18.0
CURLPAUSE_RECV 7.18.0
@@ -710,6 +732,40 @@ CURLPROXY_SOCKS4 7.10
CURLPROXY_SOCKS4A 7.18.0
CURLPROXY_SOCKS5 7.10
CURLPROXY_SOCKS5_HOSTNAME 7.18.0
+CURLPX_BAD_ADDRESS_TYPE 7.73.0
+CURLPX_BAD_VERSION 7.73.0
+CURLPX_CLOSED 7.73.0
+CURLPX_GSSAPI 7.73.0
+CURLPX_GSSAPI_PERMSG 7.73.0
+CURLPX_GSSAPI_PROTECTION 7.73.0
+CURLPX_IDENTD 7.73.0
+CURLPX_IDENTD_DIFFER 7.73.0
+CURLPX_LONG_HOSTNAME 7.73.0
+CURLPX_LONG_PASSWD 7.73.0
+CURLPX_LONG_USER 7.73.0
+CURLPX_NO_AUTH 7.73.0
+CURLPX_OK 7.73.0
+CURLPX_RECV_ADDRESS 7.73.0
+CURLPX_RECV_AUTH 7.73.0
+CURLPX_RECV_CONNECT 7.73.0
+CURLPX_RECV_REQACK 7.73.0
+CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED 7.73.0
+CURLPX_REPLY_COMMAND_NOT_SUPPORTED 7.73.0
+CURLPX_REPLY_CONNECTION_REFUSED 7.73.0
+CURLPX_REPLY_GENERAL_SERVER_FAILURE 7.73.0
+CURLPX_REPLY_HOST_UNREACHABLE 7.73.0
+CURLPX_REPLY_NETWORK_UNREACHABLE 7.73.0
+CURLPX_REPLY_NOT_ALLOWED 7.73.0
+CURLPX_REPLY_TTL_EXPIRED 7.73.0
+CURLPX_REPLY_UNASSIGNED 7.73.0
+CURLPX_REQUEST_FAILED 7.73.0
+CURLPX_RESOLVE_HOST 7.73.0
+CURLPX_SEND_AUTH 7.73.0
+CURLPX_SEND_CONNECT 7.73.0
+CURLPX_SEND_REQUEST 7.73.0
+CURLPX_UNKNOWN_FAIL 7.73.0
+CURLPX_UNKNOWN_MODE 7.73.0
+CURLPX_USER_REJECTED 7.73.0
CURLSHE_BAD_OPTION 7.10.3
CURLSHE_INVALID 7.10.3
CURLSHE_IN_USE 7.10.3
@@ -755,11 +811,14 @@ CURLSSLOPT_ALLOW_BEAST 7.25.0
CURLSSLOPT_NATIVE_CA 7.71.0
CURLSSLOPT_NO_PARTIALCHAIN 7.68.0
CURLSSLOPT_NO_REVOKE 7.44.0
+CURLSSLOPT_REVOKE_BEST_EFFORT 7.70.0
CURLSSLSET_NO_BACKENDS 7.56.0
CURLSSLSET_OK 7.56.0
-CURLSSLOPT_REVOKE_BEST_EFFORT 7.70.0
CURLSSLSET_TOO_LATE 7.56.0
CURLSSLSET_UNKNOWN_BACKEND 7.56.0
+CURLSTS_DONE 7.74.0
+CURLSTS_FAIL 7.74.0
+CURLSTS_OK 7.74.0
CURLUE_BAD_HANDLE 7.62.0
CURLUE_BAD_PARTPOINTER 7.62.0
CURLUE_BAD_PORT_NUMBER 7.62.0
@@ -953,6 +1012,7 @@ CURL_VERSION_CURLDEBUG 7.19.6
CURL_VERSION_DEBUG 7.10.6
CURL_VERSION_GSSAPI 7.38.0
CURL_VERSION_GSSNEGOTIATE 7.10.6 7.38.0
+CURL_VERSION_HSTS 7.74.0
CURL_VERSION_HTTP2 7.33.0
CURL_VERSION_HTTP3 7.66.0
CURL_VERSION_HTTPS_PROXY 7.52.0
@@ -970,9 +1030,9 @@ CURL_VERSION_SPNEGO 7.10.8
CURL_VERSION_SSL 7.10
CURL_VERSION_SSPI 7.13.2
CURL_VERSION_TLSAUTH_SRP 7.21.4
+CURL_VERSION_UNICODE 7.72.0
CURL_VERSION_UNIX_SOCKETS 7.40.0
CURL_VERSION_ZSTD 7.72.0
-CURL_VERSION_UNICODE 7.72.0
CURL_WAIT_POLLIN 7.28.0
CURL_WAIT_POLLOUT 7.28.0
CURL_WAIT_POLLPRI 7.28.0
diff --git a/docs/libcurl/symbols.pl b/docs/libcurl/symbols.pl
index 7e92ea052..3a1aef8ca 100755
--- a/docs/libcurl/symbols.pl
+++ b/docs/libcurl/symbols.pl
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/docs/mk-ca-bundle.1 b/docs/mk-ca-bundle.1
index d491cb914..94f752d12 100644
--- a/docs/mk-ca-bundle.1
+++ b/docs/mk-ca-bundle.1
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -136,7 +136,7 @@ Returns 1 if it fails to download data.
This manual page was initially written by
.An Jan Schaumann Aq Mt jschauma@netmeister.org
and converted to mdoc format by
-.An Nils Gillmann Aq Mt ng0@n0.is .
+.An Nikita Gillmann Aq Mt nikita@n0.is .
.Sh SEE ALSO
.Xr curl 1
.Sh STANDARDS
@@ -146,7 +146,7 @@ The file format used by Mozilla for this trust information seems to be documente
.Nm
is a command line tool that is shipped as part of every
curl and libcurl release (see
-.Lk https://curl.haxx.se/
+.Lk https://curl.se/
).
It was originally based
on the parse-certs script written by Roland Krikava and was later much
diff --git a/docs/options-in-versions b/docs/options-in-versions
index 1a27306ae..97c416d83 100644
--- a/docs/options-in-versions
+++ b/docs/options-in-versions
@@ -32,6 +32,7 @@
--create-dirs 7.10.3
--crlf 5.7
--crlfile 7.19.7
+--curves 7.73.0
--data (-d) 4.0
--data-ascii 7.2
--data-binary 7.2
@@ -78,6 +79,7 @@
--header (-H) 5.0
--help (-h) 4.0
--hostpubmd5 7.17.1
+--hsts 7.74.0
--http0.9 7.64.0
--http1.0 (-0) 7.9.1
--http1.1 7.33.0
@@ -127,6 +129,7 @@
--ntlm-wb 7.22.0
--oauth2-bearer 7.33.0
--output (-o) 4.0
+--output-dir 7.73.0
--parallel (-Z) 7.66.0
--parallel-immediate 7.68.0
--parallel-max 7.66.0
diff --git a/gnurl-config.in b/gnurl-config.in
index e5621da20..bec64b892 100644
--- a/gnurl-config.in
+++ b/gnurl-config.in
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/include/Makefile.am b/include/Makefile.am
index 1f722ddda..01e795828 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -21,6 +21,6 @@
###########################################################################
SUBDIRS = gnurl
-EXTRA_DIST = README
+EXTRA_DIST = README.md
AUTOMAKE_OPTIONS = foreign no-dependencies
diff --git a/include/README b/include/README
deleted file mode 100644
index f4cfd9a68..000000000
--- a/include/README
+++ /dev/null
@@ -1,18 +0,0 @@
- _ _ ____ _
- ___| | | | _ \| |
- / __| | | | |_) | |
- | (__| |_| | _ <| |___
- \___|\___/|_| \_\_____|
-
-Include files for libcurl, external users.
-
-They're all placed in the curl subdirectory here for better fit in any kind
-of environment. You must include files from here using...
-
- #include <gnurl/curl.h>
-
-... style and point the compiler's include path to the directory holding the
-curl subdirectory. It makes it more likely to survive future modifications.
-
-The public curl include files can be shared freely between different platforms
-and different architectures.
diff --git a/include/README.md b/include/README.md
new file mode 100644
index 000000000..bd28a30e8
--- /dev/null
+++ b/include/README.md
@@ -0,0 +1,14 @@
+# include
+
+Public include files for libcurl, external users.
+
+They're all placed in the curl subdirectory here for better fit in any kind of
+environment. You must include files from here using...
+
+ #include <curl/curl.h>
+
+... style and point the compiler's include path to the directory holding the
+curl subdirectory. It makes it more likely to survive future modifications.
+
+The public curl include files can be shared freely between different platforms
+and different architectures.
diff --git a/include/gnurl/Makefile.am b/include/gnurl/Makefile.am
index b8298f29b..387a14461 100644
--- a/include/gnurl/Makefile.am
+++ b/include/gnurl/Makefile.am
@@ -5,11 +5,11 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -21,7 +21,7 @@
###########################################################################
pkginclude_HEADERS = \
curl.h curlver.h easy.h mprintf.h stdcheaders.h multi.h \
- typecheck-gcc.h system.h urlapi.h
+ typecheck-gcc.h system.h urlapi.h options.h
pkgincludedir= $(includedir)/gnurl
diff --git a/include/gnurl/curl.h b/include/gnurl/curl.h
index 5aeaca91d..a73418dce 100644
--- a/include/gnurl/curl.h
+++ b/include/gnurl/curl.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -24,7 +24,7 @@
/*
* If you have libcurl problems, all docs and details are found here:
- * https://curl.haxx.se/libcurl/
+ * https://curl.se/libcurl/
*
* curl-library mailing list subscription and unsubscription web interface:
* https://cool.haxx.se/mailman/listinfo/curl-library/
@@ -74,7 +74,7 @@
#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \
- defined(__CYGWIN__) || \
+ defined(__CYGWIN__) || defined(AMIGA) || \
(defined(__FreeBSD_version) && (__FreeBSD_version < 800000))
#include <sys/select.h>
#endif
@@ -610,6 +610,7 @@ typedef enum {
error */
CURLE_HTTP3, /* 95 - An HTTP/3 layer problem */
CURLE_QUIC_CONNECT_ERROR, /* 96 - QUIC connection error */
+ CURLE_PROXY, /* 97 - proxy handshake error */
CURL_LAST /* never use! */
} CURLcode;
@@ -689,6 +690,48 @@ typedef enum {
#endif /*!CURL_NO_OLDIES*/
+/*
+ * Proxy error codes. Returned in CURLINFO_PROXY_ERROR if CURLE_PROXY was
+ * return for the transfers.
+ */
+typedef enum {
+ CURLPX_OK,
+ CURLPX_BAD_ADDRESS_TYPE,
+ CURLPX_BAD_VERSION,
+ CURLPX_CLOSED,
+ CURLPX_GSSAPI,
+ CURLPX_GSSAPI_PERMSG,
+ CURLPX_GSSAPI_PROTECTION,
+ CURLPX_IDENTD,
+ CURLPX_IDENTD_DIFFER,
+ CURLPX_LONG_HOSTNAME,
+ CURLPX_LONG_PASSWD,
+ CURLPX_LONG_USER,
+ CURLPX_NO_AUTH,
+ CURLPX_RECV_ADDRESS,
+ CURLPX_RECV_AUTH,
+ CURLPX_RECV_CONNECT,
+ CURLPX_RECV_REQACK,
+ CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED,
+ CURLPX_REPLY_COMMAND_NOT_SUPPORTED,
+ CURLPX_REPLY_CONNECTION_REFUSED,
+ CURLPX_REPLY_GENERAL_SERVER_FAILURE,
+ CURLPX_REPLY_HOST_UNREACHABLE,
+ CURLPX_REPLY_NETWORK_UNREACHABLE,
+ CURLPX_REPLY_NOT_ALLOWED,
+ CURLPX_REPLY_TTL_EXPIRED,
+ CURLPX_REPLY_UNASSIGNED,
+ CURLPX_REQUEST_FAILED,
+ CURLPX_RESOLVE_HOST,
+ CURLPX_SEND_AUTH,
+ CURLPX_SEND_CONNECT,
+ CURLPX_SEND_REQUEST,
+ CURLPX_UNKNOWN_FAIL,
+ CURLPX_UNKNOWN_MODE,
+ CURLPX_USER_REJECTED,
+ CURLPX_LAST /* never use */
+} CURLproxycode;
+
/* This prototype applies to all conversion callbacks */
typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length);
@@ -789,6 +832,7 @@ enum curl_khstat {
CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now so
this causes a CURLE_DEFER error but otherwise the
connection will be left intact etc */
+ CURLKHSTAT_FINE_REPLACE, /* accept and replace the wrong key*/
CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */
};
@@ -905,13 +949,42 @@ typedef enum {
#define CURLHEADER_SEPARATE (1<<0)
/* CURLALTSVC_* are bits for the CURLOPT_ALTSVC_CTRL option */
-#define CURLALTSVC_IMMEDIATELY (1<<0)
-
#define CURLALTSVC_READONLYFILE (1<<2)
#define CURLALTSVC_H1 (1<<3)
#define CURLALTSVC_H2 (1<<4)
#define CURLALTSVC_H3 (1<<5)
+
+struct curl_hstsentry {
+ char *name;
+ size_t namelen;
+ unsigned int includeSubDomains:1;
+ char expire[18]; /* YYYYMMDD HH:MM:SS [null-terminated] */
+};
+
+struct curl_index {
+ size_t index; /* the provided entry's "index" or count */
+ size_t total; /* total number of entries to save */
+};
+
+typedef enum {
+ CURLSTS_OK,
+ CURLSTS_DONE,
+ CURLSTS_FAIL
+} CURLSTScode;
+
+typedef CURLSTScode (*curl_hstsread_callback)(CURL *easy,
+ struct curl_hstsentry *e,
+ void *userp);
+typedef CURLSTScode (*curl_hstswrite_callback)(CURL *easy,
+ struct curl_hstsentry *e,
+ struct curl_index *i,
+ void *userp);
+
+/* CURLHSTS_* are bits for the CURLOPT_HSTS option */
+#define CURLHSTS_ENABLE (long)(1<<0)
+#define CURLHSTS_READONLYFILE (long)(1<<1)
+
/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */
#define CURLPROTO_HTTP (1<<0)
#define CURLPROTO_HTTPS (1<<1)
@@ -958,17 +1031,27 @@ typedef enum {
#define CURLOPT(na,t,nu) na = t + nu
-/* handy aliases that make no run-time difference */
-#define CURLOPTTYPE_STRINGPOINT CURLOPTTYPE_OBJECTPOINT
+/* CURLOPT aliases that make no run-time difference */
+
+/* 'char *' argument to a string with a trailing zero */
+#define CURLOPTTYPE_STRINGPOINT CURLOPTTYPE_OBJECTPOINT
+
+/* 'struct curl_slist *' argument */
#define CURLOPTTYPE_SLISTPOINT CURLOPTTYPE_OBJECTPOINT
+/* 'void *' argument passed untouched to callback */
+#define CURLOPTTYPE_CBPOINT CURLOPTTYPE_OBJECTPOINT
+
+/* 'long' argument with a set of values/bitmask */
+#define CURLOPTTYPE_VALUES CURLOPTTYPE_LONG
+
/*
* All CURLOPT_* values.
*/
typedef enum {
/* This is the FILE * or void * the regular output should be written to. */
- CURLOPT(CURLOPT_WRITEDATA, CURLOPTTYPE_OBJECTPOINT, 1),
+ CURLOPT(CURLOPT_WRITEDATA, CURLOPTTYPE_CBPOINT, 1),
/* The full URL to get/put */
CURLOPT(CURLOPT_URL, CURLOPTTYPE_STRINGPOINT, 2),
@@ -991,7 +1074,7 @@ typedef enum {
/* not used */
/* Specified file stream to upload from (use as input): */
- CURLOPT(CURLOPT_READDATA, CURLOPTTYPE_OBJECTPOINT, 9),
+ CURLOPT(CURLOPT_READDATA, CURLOPTTYPE_CBPOINT, 9),
/* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE
* bytes big. */
@@ -1076,7 +1159,7 @@ typedef enum {
/* send FILE * or void * to store headers to, if you use a callback it
is simply passed to the callback unmodified */
- CURLOPT(CURLOPT_HEADERDATA, CURLOPTTYPE_OBJECTPOINT, 29),
+ CURLOPT(CURLOPT_HEADERDATA, CURLOPTTYPE_CBPOINT, 29),
/* point to a file to read the initial cookies from, also enables
"cookie awareness" */
@@ -1084,10 +1167,10 @@ typedef enum {
/* What version to specifically try to use.
See CURL_SSLVERSION defines below. */
- CURLOPT(CURLOPT_SSLVERSION, CURLOPTTYPE_LONG, 32),
+ CURLOPT(CURLOPT_SSLVERSION, CURLOPTTYPE_VALUES, 32),
/* What kind of HTTP time condition to use, see defines */
- CURLOPT(CURLOPT_TIMECONDITION, CURLOPTTYPE_LONG, 33),
+ CURLOPT(CURLOPT_TIMECONDITION, CURLOPTTYPE_VALUES, 33),
/* Time to use with the above condition. Specified in number of seconds
since 1 Jan 1970 */
@@ -1141,7 +1224,7 @@ typedef enum {
/* Specify whether to read the user+password from the .netrc or the URL.
* This must be one of the CURL_NETRC_* enums below. */
- CURLOPT(CURLOPT_NETRC, CURLOPTTYPE_LONG, 51),
+ CURLOPT(CURLOPT_NETRC, CURLOPTTYPE_VALUES, 51),
/* use Location: Luke! */
CURLOPT(CURLOPT_FOLLOWLOCATION, CURLOPTTYPE_LONG, 52),
@@ -1162,8 +1245,8 @@ typedef enum {
/* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION
callbacks */
- CURLOPT(CURLOPT_PROGRESSDATA, CURLOPTTYPE_OBJECTPOINT, 57),
-#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA
+ CURLOPT(CURLOPT_XFERINFODATA, CURLOPTTYPE_CBPOINT, 57),
+#define CURLOPT_PROGRESSDATA CURLOPT_XFERINFODATA
/* We want the referrer field set automatically when following locations */
CURLOPT(CURLOPT_AUTOREFERER, CURLOPTTYPE_LONG, 58),
@@ -1258,7 +1341,7 @@ typedef enum {
/* Specify which HTTP version to use! This must be set to one of the
CURL_HTTP_VERSION* enums set below. */
- CURLOPT(CURLOPT_HTTP_VERSION, CURLOPTTYPE_LONG, 84),
+ CURLOPT(CURLOPT_HTTP_VERSION, CURLOPTTYPE_VALUES, 84),
/* Specifically switch on or off the FTP engine's use of the EPSV command. By
default, that one will always be attempted before the more traditional
@@ -1296,7 +1379,7 @@ typedef enum {
CURLOPT(CURLOPT_DEBUGFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 94),
/* set the data for the debug function */
- CURLOPT(CURLOPT_DEBUGDATA, CURLOPTTYPE_OBJECTPOINT, 95),
+ CURLOPT(CURLOPT_DEBUGDATA, CURLOPTTYPE_CBPOINT, 95),
/* mark this as start of a cookie session */
CURLOPT(CURLOPT_COOKIESESSION, CURLOPTTYPE_LONG, 96),
@@ -1319,7 +1402,7 @@ typedef enum {
/* indicates type of proxy. accepted values are CURLPROXY_HTTP (default),
CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and
CURLPROXY_SOCKS5. */
- CURLOPT(CURLOPT_PROXYTYPE, CURLOPTTYPE_LONG, 101),
+ CURLOPT(CURLOPT_PROXYTYPE, CURLOPTTYPE_VALUES, 101),
/* Set the Accept-Encoding string. Use this to tell a server you would like
the response to be compressed. Before 7.21.6, this was known as
@@ -1345,7 +1428,7 @@ typedef enum {
/* Set this to a bitmask value to enable the particular authentications
methods you like. Use this in combination with CURLOPT_USERPWD.
Note that setting multiple bits may cause extra network round-trips. */
- CURLOPT(CURLOPT_HTTPAUTH, CURLOPTTYPE_LONG, 107),
+ CURLOPT(CURLOPT_HTTPAUTH, CURLOPTTYPE_VALUES, 107),
/* Set the ssl context callback function, currently only for OpenSSL or
WolfSSL ssl_ctx, or mbedTLS mbedtls_ssl_config in the second argument.
@@ -1354,7 +1437,7 @@ typedef enum {
/* Set the userdata for the ssl context callback function's third
argument */
- CURLOPT(CURLOPT_SSL_CTX_DATA, CURLOPTTYPE_OBJECTPOINT, 109),
+ CURLOPT(CURLOPT_SSL_CTX_DATA, CURLOPTTYPE_CBPOINT, 109),
/* FTP Option that causes missing dirs to be created on the remote server.
In 7.19.4 we introduced the convenience enums for this option using the
@@ -1365,7 +1448,7 @@ typedef enum {
/* Set this to a bitmask value to enable the particular authentications
methods you like. Use this in combination with CURLOPT_PROXYUSERPWD.
Note that setting multiple bits may cause extra network round-trips. */
- CURLOPT(CURLOPT_PROXYAUTH, CURLOPTTYPE_LONG, 111),
+ CURLOPT(CURLOPT_PROXYAUTH, CURLOPTTYPE_VALUES, 111),
/* FTP option that changes the timeout, in seconds, associated with
getting a response. This is different from transfer timeout time and
@@ -1377,7 +1460,7 @@ typedef enum {
/* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to
tell libcurl to resolve names to those IP versions only. This only has
affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */
- CURLOPT(CURLOPT_IPRESOLVE, CURLOPTTYPE_LONG, 113),
+ CURLOPT(CURLOPT_IPRESOLVE, CURLOPTTYPE_VALUES, 113),
/* Set this option to limit the size of a file that will be downloaded from
an HTTP or FTP server.
@@ -1412,7 +1495,7 @@ typedef enum {
CURLUSESSL_CONTROL - SSL for the control connection or fail
CURLUSESSL_ALL - SSL for all communication or fail
*/
- CURLOPT(CURLOPT_USE_SSL, CURLOPTTYPE_LONG, 119),
+ CURLOPT(CURLOPT_USE_SSL, CURLOPTTYPE_VALUES, 119),
/* The _LARGE version of the standard POSTFIELDSIZE option */
CURLOPT(CURLOPT_POSTFIELDSIZE_LARGE, CURLOPTTYPE_OFF_T, 120),
@@ -1438,10 +1521,10 @@ typedef enum {
CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS
CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL
*/
- CURLOPT(CURLOPT_FTPSSLAUTH, CURLOPTTYPE_LONG, 129),
+ CURLOPT(CURLOPT_FTPSSLAUTH, CURLOPTTYPE_VALUES, 129),
CURLOPT(CURLOPT_IOCTLFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 130),
- CURLOPT(CURLOPT_IOCTLDATA, CURLOPTTYPE_OBJECTPOINT, 131),
+ CURLOPT(CURLOPT_IOCTLDATA, CURLOPTTYPE_CBPOINT, 131),
/* 132 OBSOLETE. Gone in 7.16.0 */
/* 133 OBSOLETE. Gone in 7.16.0 */
@@ -1464,7 +1547,7 @@ typedef enum {
/* Select "file method" to use when doing FTP, see the curl_ftpmethod
above. */
- CURLOPT(CURLOPT_FTP_FILEMETHOD, CURLOPTTYPE_LONG, 138),
+ CURLOPT(CURLOPT_FTP_FILEMETHOD, CURLOPTTYPE_VALUES, 138),
/* Local port number to bind the socket to */
CURLOPT(CURLOPT_LOCALPORT, CURLOPTTYPE_LONG, 139),
@@ -1501,14 +1584,14 @@ typedef enum {
/* callback function for setting socket options */
CURLOPT(CURLOPT_SOCKOPTFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 148),
- CURLOPT(CURLOPT_SOCKOPTDATA, CURLOPTTYPE_OBJECTPOINT, 149),
+ CURLOPT(CURLOPT_SOCKOPTDATA, CURLOPTTYPE_CBPOINT, 149),
/* set to 0 to disable session ID re-use for this transfer, default is
enabled (== 1) */
CURLOPT(CURLOPT_SSL_SESSIONID_CACHE, CURLOPTTYPE_LONG, 150),
/* allowed SSH authentication methods */
- CURLOPT(CURLOPT_SSH_AUTH_TYPES, CURLOPTTYPE_LONG, 151),
+ CURLOPT(CURLOPT_SSH_AUTH_TYPES, CURLOPTTYPE_VALUES, 151),
/* Used by scp/sftp to do public/private key authentication */
CURLOPT(CURLOPT_SSH_PUBLIC_KEYFILE, CURLOPTTYPE_STRINGPOINT, 152),
@@ -1533,7 +1616,7 @@ typedef enum {
/* Set the behaviour of POST when redirecting. Values must be set to one
of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */
- CURLOPT(CURLOPT_POSTREDIR, CURLOPTTYPE_LONG, 161),
+ CURLOPT(CURLOPT_POSTREDIR, CURLOPTTYPE_VALUES, 161),
/* used by scp/sftp to verify the host's public key */
CURLOPT(CURLOPT_SSH_HOST_PUBLIC_KEY_MD5, CURLOPTTYPE_STRINGPOINT, 162),
@@ -1543,7 +1626,7 @@ typedef enum {
CURL_SOCKET_BAD. The callback should have type
curl_opensocket_callback */
CURLOPT(CURLOPT_OPENSOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 163),
- CURLOPT(CURLOPT_OPENSOCKETDATA, CURLOPTTYPE_OBJECTPOINT, 164),
+ CURLOPT(CURLOPT_OPENSOCKETDATA, CURLOPTTYPE_CBPOINT, 164),
/* POST volatile input fields. */
CURLOPT(CURLOPT_COPYPOSTFIELDS, CURLOPTTYPE_OBJECTPOINT, 165),
@@ -1553,7 +1636,7 @@ typedef enum {
/* Callback function for seeking in the input stream */
CURLOPT(CURLOPT_SEEKFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 167),
- CURLOPT(CURLOPT_SEEKDATA, CURLOPTTYPE_OBJECTPOINT, 168),
+ CURLOPT(CURLOPT_SEEKDATA, CURLOPTTYPE_CBPOINT, 168),
/* CRL file */
CURLOPT(CURLOPT_CRLFILE, CURLOPTTYPE_STRINGPOINT, 169),
@@ -1614,7 +1697,7 @@ typedef enum {
CURLOPT(CURLOPT_SSH_KEYFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 184),
/* set the SSH host key callback custom pointer */
- CURLOPT(CURLOPT_SSH_KEYDATA, CURLOPTTYPE_OBJECTPOINT, 185),
+ CURLOPT(CURLOPT_SSH_KEYDATA, CURLOPTTYPE_CBPOINT, 185),
/* set the SMTP mail originator */
CURLOPT(CURLOPT_MAIL_FROM, CURLOPTTYPE_STRINGPOINT, 186),
@@ -1626,7 +1709,7 @@ typedef enum {
CURLOPT(CURLOPT_FTP_USE_PRET, CURLOPTTYPE_LONG, 188),
/* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */
- CURLOPT(CURLOPT_RTSP_REQUEST, CURLOPTTYPE_LONG, 189),
+ CURLOPT(CURLOPT_RTSP_REQUEST, CURLOPTTYPE_VALUES, 189),
/* The RTSP session identifier */
CURLOPT(CURLOPT_RTSP_SESSION_ID, CURLOPTTYPE_STRINGPOINT, 190),
@@ -1644,7 +1727,7 @@ typedef enum {
CURLOPT(CURLOPT_RTSP_SERVER_CSEQ, CURLOPTTYPE_LONG, 194),
/* The stream to pass to INTERLEAVEFUNCTION. */
- CURLOPT(CURLOPT_INTERLEAVEDATA, CURLOPTTYPE_OBJECTPOINT, 195),
+ CURLOPT(CURLOPT_INTERLEAVEDATA, CURLOPTTYPE_CBPOINT, 195),
/* Let the application define a custom write method for RTP data */
CURLOPT(CURLOPT_INTERLEAVEFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 196),
@@ -1664,10 +1747,10 @@ typedef enum {
CURLOPT(CURLOPT_FNMATCH_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 200),
/* Let the application define custom chunk data pointer */
- CURLOPT(CURLOPT_CHUNK_DATA, CURLOPTTYPE_OBJECTPOINT, 201),
+ CURLOPT(CURLOPT_CHUNK_DATA, CURLOPTTYPE_CBPOINT, 201),
/* FNMATCH_FUNCTION user pointer */
- CURLOPT(CURLOPT_FNMATCH_DATA, CURLOPTTYPE_OBJECTPOINT, 202),
+ CURLOPT(CURLOPT_FNMATCH_DATA, CURLOPTTYPE_CBPOINT, 202),
/* send linked-list of name:port:address sets */
CURLOPT(CURLOPT_RESOLVE, CURLOPTTYPE_SLISTPOINT, 203),
@@ -1696,10 +1779,10 @@ typedef enum {
/* Callback function for closing socket (instead of close(2)). The callback
should have type curl_closesocket_callback */
CURLOPT(CURLOPT_CLOSESOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 208),
- CURLOPT(CURLOPT_CLOSESOCKETDATA, CURLOPTTYPE_OBJECTPOINT, 209),
+ CURLOPT(CURLOPT_CLOSESOCKETDATA, CURLOPTTYPE_CBPOINT, 209),
/* allow GSSAPI credential delegation */
- CURLOPT(CURLOPT_GSSAPI_DELEGATION, CURLOPTTYPE_LONG, 210),
+ CURLOPT(CURLOPT_GSSAPI_DELEGATION, CURLOPTTYPE_VALUES, 210),
/* Set the name servers to use for DNS resolution */
CURLOPT(CURLOPT_DNS_SERVERS, CURLOPTTYPE_STRINGPOINT, 211),
@@ -1716,7 +1799,7 @@ typedef enum {
CURLOPT(CURLOPT_TCP_KEEPINTVL, CURLOPTTYPE_LONG, 215),
/* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */
- CURLOPT(CURLOPT_SSL_OPTIONS, CURLOPTTYPE_LONG, 216),
+ CURLOPT(CURLOPT_SSL_OPTIONS, CURLOPTTYPE_VALUES, 216),
/* Set the SMTP auth originator */
CURLOPT(CURLOPT_MAIL_AUTH, CURLOPTTYPE_STRINGPOINT, 217),
@@ -1763,7 +1846,7 @@ typedef enum {
CURLOPT(CURLOPT_PROXYHEADER, CURLOPTTYPE_SLISTPOINT, 228),
/* Pass in a bitmask of "header options" */
- CURLOPT(CURLOPT_HEADEROPT, CURLOPTTYPE_LONG, 229),
+ CURLOPT(CURLOPT_HEADEROPT, CURLOPTTYPE_VALUES, 229),
/* The public key in DER form used to validate the peer public key
this option is used only if SSL_VERIFYPEER is true */
@@ -1835,7 +1918,7 @@ typedef enum {
/* What version to specifically try to use for proxy.
See CURL_SSLVERSION defines below. */
- CURLOPT(CURLOPT_PROXY_SSLVERSION, CURLOPTTYPE_LONG, 250),
+ CURLOPT(CURLOPT_PROXY_SSLVERSION, CURLOPTTYPE_VALUES, 250),
/* Set a username for authenticated TLS for proxy */
CURLOPT(CURLOPT_PROXY_TLSAUTH_USERNAME, CURLOPTTYPE_STRINGPOINT, 251),
@@ -1909,7 +1992,7 @@ typedef enum {
CURLOPT(CURLOPT_RESOLVER_START_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 272),
/* User data to pass to the resolver start callback. */
- CURLOPT(CURLOPT_RESOLVER_START_DATA, CURLOPTTYPE_OBJECTPOINT, 273),
+ CURLOPT(CURLOPT_RESOLVER_START_DATA, CURLOPTTYPE_CBPOINT, 273),
/* send HAProxy PROXY protocol header? */
CURLOPT(CURLOPT_HAPROXYPROTOCOL, CURLOPTTYPE_LONG, 274),
@@ -1940,7 +2023,7 @@ typedef enum {
CURLOPT(CURLOPT_TRAILERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 283),
/* pointer to be passed to HTTP_TRAILER_FUNCTION */
- CURLOPT(CURLOPT_TRAILERDATA, CURLOPTTYPE_OBJECTPOINT, 284),
+ CURLOPT(CURLOPT_TRAILERDATA, CURLOPTTYPE_CBPOINT, 284),
/* set this to 1L to allow HTTP/0.9 responses or 0L to disallow */
CURLOPT(CURLOPT_HTTP09_ALLOWED, CURLOPTTYPE_LONG, 285),
@@ -1971,6 +2054,25 @@ typedef enum {
CURLOPT(CURLOPT_PROXY_ISSUERCERT, CURLOPTTYPE_STRINGPOINT, 296),
CURLOPT(CURLOPT_PROXY_ISSUERCERT_BLOB, CURLOPTTYPE_BLOB, 297),
+ /* the EC curves requested by the TLS client (RFC 8422, 5.1);
+ * OpenSSL support via 'set_groups'/'set_curves':
+ * https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_groups.html
+ */
+ CURLOPT(CURLOPT_SSL_EC_CURVES, CURLOPTTYPE_STRINGPOINT, 298),
+
+ /* HSTS bitmask */
+ CURLOPT(CURLOPT_HSTS_CTRL, CURLOPTTYPE_LONG, 299),
+ /* HSTS file name */
+ CURLOPT(CURLOPT_HSTS, CURLOPTTYPE_STRINGPOINT, 300),
+
+ /* HSTS read callback */
+ CURLOPT(CURLOPT_HSTSREADFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 301),
+ CURLOPT(CURLOPT_HSTSREADDATA, CURLOPTTYPE_CBPOINT, 302),
+
+ /* HSTS write callback */
+ CURLOPT(CURLOPT_HSTSWRITEFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 303),
+ CURLOPT(CURLOPT_HSTSWRITEDATA, CURLOPTTYPE_CBPOINT, 304),
+
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
@@ -2643,8 +2745,9 @@ typedef enum {
CURLINFO_APPCONNECT_TIME_T = CURLINFO_OFF_T + 56,
CURLINFO_RETRY_AFTER = CURLINFO_OFF_T + 57,
CURLINFO_EFFECTIVE_METHOD = CURLINFO_STRING + 58,
+ CURLINFO_PROXY_ERROR = CURLINFO_LONG + 59,
- CURLINFO_LASTONE = 58
+ CURLINFO_LASTONE = 59
} CURLINFO;
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
@@ -2841,6 +2944,7 @@ typedef struct curl_version_info_data curl_version_info_data;
#define CURL_VERSION_HTTP3 (1<<25) /* HTTP3 support built-in */
#define CURL_VERSION_ZSTD (1<<26) /* zstd features are present */
#define CURL_VERSION_UNICODE (1<<27) /* Unicode support on Windows */
+#define CURL_VERSION_HSTS (1<<28) /* HSTS is supported */
/*
* NAME curl_version_info()
@@ -2903,6 +3007,7 @@ CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask);
#include "easy.h" /* nothing in curl is fun without the easy stuff */
#include "multi.h"
#include "urlapi.h"
+#include "options.h"
/* the typechecker doesn't work in C++ (yet) */
#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \
diff --git a/include/gnurl/curlver.h b/include/gnurl/curlver.h
index b9fd7e6d6..5990e6ce5 100644
--- a/include/gnurl/curlver.h
+++ b/include/gnurl/curlver.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -30,12 +30,12 @@
/* This is the version number of the libcurl package from which this header
file origins: */
-#define LIBCURL_VERSION "7.72.0-DEV"
+#define LIBCURL_VERSION "7.74.0-DEV"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBCURL_VERSION_MAJOR 7
-#define LIBCURL_VERSION_MINOR 72
+#define LIBCURL_VERSION_MINOR 74
#define LIBCURL_VERSION_PATCH 0
/* This is the numeric version of the libcurl version number, meant for easier
@@ -57,7 +57,7 @@
CURL_VERSION_BITS() macro since curl's own configure script greps for it
and needs it to contain the full number.
*/
-#define LIBCURL_VERSION_NUM 0x074800
+#define LIBCURL_VERSION_NUM 0x074a00
/*
* This is the date and time when the full source package was created. The
diff --git a/include/gnurl/easy.h b/include/gnurl/easy.h
index 9aef13396..2dbfb26b5 100644
--- a/include/gnurl/easy.h
+++ b/include/gnurl/easy.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/include/gnurl/mprintf.h b/include/gnurl/mprintf.h
index f615ed7d6..3549552db 100644
--- a/include/gnurl/mprintf.h
+++ b/include/gnurl/mprintf.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/include/gnurl/multi.h b/include/gnurl/multi.h
index 4ea8b267c..87d74144a 100644
--- a/include/gnurl/multi.h
+++ b/include/gnurl/multi.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/include/gnurl/options.h b/include/gnurl/options.h
new file mode 100644
index 000000000..14373b551
--- /dev/null
+++ b/include/gnurl/options.h
@@ -0,0 +1,68 @@
+#ifndef CURLINC_OPTIONS_H
+#define CURLINC_OPTIONS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2018 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ CURLOT_LONG, /* long (a range of values) */
+ CURLOT_VALUES, /* (a defined set or bitmask) */
+ CURLOT_OFF_T, /* curl_off_t (a range of values) */
+ CURLOT_OBJECT, /* pointer (void *) */
+ CURLOT_STRING, /* (char * to zero terminated buffer) */
+ CURLOT_SLIST, /* (struct curl_slist *) */
+ CURLOT_CBPTR, /* (void * passed as-is to a callback) */
+ CURLOT_BLOB, /* blob (struct curl_blob *) */
+ CURLOT_FUNCTION /* function pointer */
+} curl_easytype;
+
+/* Flag bits */
+
+/* "alias" means it is provided for old programs to remain functional,
+ we prefer another name */
+#define CURLOT_FLAG_ALIAS (1<<0)
+
+/* The CURLOPTTYPE_* id ranges can still be used to figure out what type/size
+ to use for curl_easy_setopt() for the given id */
+struct curl_easyoption {
+ const char *name;
+ CURLoption id;
+ curl_easytype type;
+ unsigned int flags;
+};
+
+CURL_EXTERN const struct curl_easyoption *
+curl_easy_option_by_name(const char *name);
+
+CURL_EXTERN const struct curl_easyoption *
+curl_easy_option_by_id (CURLoption id);
+
+CURL_EXTERN const struct curl_easyoption *
+curl_easy_option_next(const struct curl_easyoption *prev);
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+#endif /* CURLINC_OPTIONS_H */
diff --git a/include/gnurl/stdcheaders.h b/include/gnurl/stdcheaders.h
index a6bdc1a25..60596c756 100644
--- a/include/gnurl/stdcheaders.h
+++ b/include/gnurl/stdcheaders.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/include/gnurl/system.h b/include/gnurl/system.h
index 867af6141..faf8fcf84 100644
--- a/include/gnurl/system.h
+++ b/include/gnurl/system.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/include/gnurl/typecheck-gcc.h b/include/gnurl/typecheck-gcc.h
index f8cb921f2..6d84150dc 100644
--- a/include/gnurl/typecheck-gcc.h
+++ b/include/gnurl/typecheck-gcc.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -273,6 +273,7 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
(option) == CURLOPT_FTPPORT || \
(option) == CURLOPT_FTP_ACCOUNT || \
(option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \
+ (option) == CURLOPT_HSTS || \
(option) == CURLOPT_INTERFACE || \
(option) == CURLOPT_ISSUERCERT || \
(option) == CURLOPT_KEYPASSWD || \
@@ -292,6 +293,7 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
(option) == CURLOPT_PROXY_CAINFO || \
(option) == CURLOPT_PROXY_CAPATH || \
(option) == CURLOPT_PROXY_CRLFILE || \
+ (option) == CURLOPT_PROXY_ISSUERCERT || \
(option) == CURLOPT_PROXY_KEYPASSWD || \
(option) == CURLOPT_PROXY_PINNEDPUBLICKEY || \
(option) == CURLOPT_PROXY_SERVICE_NAME || \
@@ -334,6 +336,7 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
(option) == CURLOPT_USERNAME || \
(option) == CURLOPT_USERPWD || \
(option) == CURLOPT_XOAUTH2_BEARER || \
+ (option) == CURLOPT_SSL_EC_CURVES || \
0)
/* evaluates to true if option takes a curl_write_callback argument */
@@ -354,10 +357,11 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
(option) == CURLOPT_DEBUGDATA || \
(option) == CURLOPT_FNMATCH_DATA || \
(option) == CURLOPT_HEADERDATA || \
+ (option) == CURLOPT_HSTSREADDATA || \
+ (option) == CURLOPT_HSTSWRITEDATA || \
(option) == CURLOPT_INTERLEAVEDATA || \
(option) == CURLOPT_IOCTLDATA || \
(option) == CURLOPT_OPENSOCKETDATA || \
- (option) == CURLOPT_PRIVATE || \
(option) == CURLOPT_PROGRESSDATA || \
(option) == CURLOPT_READDATA || \
(option) == CURLOPT_SEEKDATA || \
diff --git a/include/gnurl/urlapi.h b/include/gnurl/urlapi.h
index f2d06770d..7343cb659 100644
--- a/include/gnurl/urlapi.h
+++ b/include/gnurl/urlapi.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2018 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2018 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/.gitattributes b/lib/.gitattributes
index 563eba7fd..8b1378917 100644
--- a/lib/.gitattributes
+++ b/lib/.gitattributes
@@ -1 +1 @@
-objnames.inc eol=lf
+
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 94f59159d..6421655e2 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -39,7 +39,7 @@ list(APPEND HHEADERS
${CMAKE_CURRENT_BINARY_DIR}/curl_config.h
)
-if(MSVC)
+if(WIN32)
list(APPEND CSOURCES libcurl.rc)
endif()
@@ -50,15 +50,6 @@ endif()
# # strtoofft.c - specify later
# )
-# # if we have Kerberos 4, right now this is never on
-# #OPTION(CURL_KRB4 "Use Kerberos 4" OFF)
-# IF(CURL_KRB4)
-# SET(CSOURCES ${CSOURCES}
-# krb4.c
-# security.c
-# )
-# ENDIF(CURL_KRB4)
-
# #OPTION(CURL_MALLOC_DEBUG "Debug mallocs in Curl" OFF)
# MARK_AS_ADVANCED(CURL_MALLOC_DEBUG)
# IF(CURL_MALLOC_DEBUG)
@@ -97,10 +88,6 @@ add_library(
ALIAS ${LIB_NAME}
)
-if(MSVC AND NOT BUILD_SHARED_LIBS)
- set_target_properties(${LIB_NAME} PROPERTIES STATIC_LIBRARY_FLAGS ${CMAKE_EXE_LINKER_FLAGS})
-endif()
-
if(NOT BUILD_SHARED_LIBS)
set_target_properties(${LIB_NAME} PROPERTIES INTERFACE_COMPILE_DEFINITIONS CURL_STATICLIB)
endif()
diff --git a/lib/Makefile.Watcom b/lib/Makefile.Watcom
deleted file mode 100644
index 6ea975b53..000000000
--- a/lib/Makefile.Watcom
+++ /dev/null
@@ -1,274 +0,0 @@
-#***************************************************************************
-# _ _ ____ _
-# Project ___| | | | _ \| |
-# / __| | | | |_) | |
-# | (__| |_| | _ <| |___
-# \___|\___/|_| \_\_____|
-#
-# Copyright (C) 2005 - 2009, Gisle Vanem <gvanem@yahoo.no>.
-# Copyright (C) 2005 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
-#
-# This software is licensed as described in the file COPYING, which
-# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
-#
-# You may opt to use, copy, modify, merge, publish, distribute and/or sell
-# copies of the Software, and permit persons to whom the Software is
-# furnished to do so, under the terms of the COPYING file.
-#
-# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
-# KIND, either express or implied.
-#
-#***************************************************************************
-
-#
-# Watcom / OpenWatcom / Win32 makefile for libcurl.
-#
-
-.ERASE
-
-!if $(__VERSION__) < 1280
-!message !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-!message ! This Open Watcom version is too old and is no longer supported !
-!message ! Please download latest version from www.openwatcom.org !
-!message !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-!error Unsupported version of Open Watcom
-!endif
-
-!ifndef %watcom
-!error WATCOM environment variable not set!
-!endif
-
-# In order to process Makefile.inc wmake must be called with -u switch!
-!ifndef %MAKEFLAGS
-!error You MUST call wmake with the -u switch!
-!endif
-
-!ifdef %libname
-LIBNAME = $(%libname)
-!else
-LIBNAME = libcurl
-!endif
-TARGETS = $(LIBNAME).dll $(LIBNAME).lib
-
-CC = wcc386
-LD = wlink
-AR = wlib
-RC = wrc
-
-!ifdef __LOADDLL__
-! loaddll wcc386 wccd386
-! loaddll wpp386 wppd386
-! loaddll wlib wlibd
-! loaddll wlink wlinkd
-!endif
-
-!ifdef __LINUX__
-CP = cp
-MD = mkdir -p
-!else
-CP = copy 2>NUL
-MD = mkdir
-!endif
-!if $(__VERSION__) > 1290
-RD = rm -rf
-!else ifdef __UNIX__
-RD = rm -rf
-!else
-RD = rmdir /q /s 2>NUL
-!endif
-
-SYS_INCL = -I"$(%watcom)/h/nt" -I"$(%watcom)/h"
-
-CFLAGS = -3r -mf -hc -zff -zgf -zq -zm -zc -s -fr=con -w2 -fpi -oilrtfm &
- -wcd=201 -bt=nt -d+ -dWIN32 &
- -dBUILDING_LIBCURL -I. -I"../include" $(SYS_INCL)
-
-!ifdef %debug
-DEBUG = -dDEBUG=1 -dDEBUGBUILD
-CFLAGS += -d3 $(DEBUG)
-!else
-CFLAGS += -d0
-!endif
-
-!ifdef %use_ipv6
-CFLAGS += -d_WIN32_WINNT=0x0501 -dENABLE_IPV6
-!endif
-
-!ifdef %use_sspi
-CFLAGS += -dUSE_WINDOWS_SSPI
-!endif
-
-!ifdef %use_winssl
-CFLAGS += -dUSE_WINDOWS_SSPI
-CFLAGS += -DUSE_SCHANNEL
-!endif
-
-!ifdef %use_winidn
-CFLAGS += -dWINVER=0x0600 -dUSE_WIN32_IDN
-! if $(__VERSION__) <= 1290
-CFLAGS += -dWANT_IDN_PROTOTYPES
-! endif
-!endif
-
-#
-# Change to suite.
-#
-!ifdef %zlib_root
-ZLIB_ROOT = $(%zlib_root)
-!else
-ZLIB_ROOT = ../../zlib-1.2.8
-!endif
-
-!ifdef %libssh2_root
-LIBSSH2_ROOT = $(%libssh2_root)
-!else
-LIBSSH2_ROOT = ../../libssh2-1.5.0
-!endif
-
-!ifdef %librtmp_root
-LIBRTMP_ROOT = $(%librtmp_root)
-!else
-LIBRTMP_ROOT = ../../rtmpdump-2.3
-!endif
-
-!ifdef %openssl_root
-OPENSSL_ROOT = $(%openssl_root)
-!else
-OPENSSL_ROOT = ../../openssl-1.0.2a
-!endif
-
-!ifdef %ares_root
-ARES_ROOT = $(%ares_root)
-!else
-ARES_ROOT = ../ares
-!endif
-
-!ifdef %use_zlib
-CFLAGS += -dHAVE_ZLIB_H -dHAVE_LIBZ -I"$(ZLIB_ROOT)"
-!endif
-
-!ifdef %use_rtmp
-CFLAGS += -dUSE_LIBRTMP -I"$(LIBRTMP_ROOT)"
-!endif
-
-!ifdef %use_ssh2
-CFLAGS += -DUSE_LIBSSH2 -DHAVE_LIBSSH2_H -I"$(LIBSSH2_ROOT)/include" -I"$(LIBSSH2_ROOT)/win32"
-!endif
-
-!ifdef %use_ssl
-CFLAGS += -wcd=138 -dUSE_OPENSSL -I"$(OPENSSL_ROOT)/inc32"
-!endif
-
-!ifdef %use_ares
-CFLAGS += -dUSE_ARES -I"$(ARES_ROOT)"
-!endif
-
-!ifdef %use_watt32
-CFLAGS += -dUSE_WATT32 -I"$(%watt_root)/inc"
-!endif
-
-OBJ_BASE = WC_Win32.obj
-!if $(__VERSION__) > 1290
-OBJ_STAT = $(OBJ_BASE)/stat
-OBJ_DYN = $(OBJ_BASE)/dyn
-!else ifdef __UNIX__
-OBJ_STAT = $(OBJ_BASE)/stat
-OBJ_DYN = $(OBJ_BASE)/dyn
-!else
-OBJ_STAT = $(OBJ_BASE)\stat
-OBJ_DYN = $(OBJ_BASE)\dyn
-!endif
-
-LINK_ARG = $(OBJ_DYN)/wlink.arg
-LIB_ARG = $(OBJ_STAT)/wlib.arg
-
-!include Makefile.inc
-
-OBJS1 = ./$(CSOURCES:.c=.obj)
-OBJS2 = $(OBJS1:vtls/=)
-OBJS3 = $(OBJS2:vauth/=)
-OBJS4 = $(OBJS3: = ./)
-OBJS_STAT = $(OBJS4:./=$(OBJ_STAT)/)
-OBJS_DYN = $(OBJS4:./=$(OBJ_DYN)/)
-
-RESOURCE = $(OBJ_DYN)/libcurl.res
-
-DIRS = $(OBJ_BASE) $(OBJ_BASE)/stat $(OBJ_BASE)/dyn
-
-.c : vauth vtls
-
-all: $(DIRS) $(TARGETS) .SYMBOLIC
- @echo Welcome to libcurl
-
-clean: .SYMBOLIC
- -rm -f $(OBJS_STAT)
- -rm -f $(OBJS_DYN)
- -rm -f $(RESOURCE) $(LINK_ARG) $(LIB_ARG)
-
-vclean distclean: clean .SYMBOLIC
- -rm -f $(TARGETS) $(LIBNAME).map $(LIBNAME).sym
- -$(RD) $(OBJ_STAT)
- -$(RD) $(OBJ_DYN)
- -$(RD) $(OBJ_BASE)
-
-$(DIRS):
- -$(MD) $^@
-
-$(LIBNAME).dll: $(OBJS_DYN) $(RESOURCE) $(__MAKEFILES__)
- %create $(LINK_ARG)
- @%append $(LINK_ARG) system nt dll
-!ifdef %debug
- @%append $(LINK_ARG) debug all
- @%append $(LINK_ARG) option symfile
-!endif
- @%append $(LINK_ARG) option quiet, caseexact, eliminate
- @%append $(LINK_ARG) option map=$(OBJ_DYN)/$(LIBNAME).map
- @%append $(LINK_ARG) option implib=$(LIBNAME)_imp.lib
- @%append $(LINK_ARG) option res=$(RESOURCE)
- @for %f in ($(OBJS_DYN)) do @%append $(LINK_ARG) file %f
- @%append $(LINK_ARG) library wldap32.lib
-!ifdef %use_watt32
- @%append $(LINK_ARG) library '$(%watt_root)/lib/wattcpw_imp.lib'
-!else
- @%append $(LINK_ARG) library ws2_32.lib
-!endif
-!ifdef %use_zlib
- @%append $(LINK_ARG) library '$(ZLIB_ROOT)/zlib.lib'
-!endif
-!ifdef %use_rtmp
- @%append $(LINK_ARG) library '$(LIBRTMP_ROOT)/librtmp/librtmp.lib'
-!endif
-!ifdef %use_ssh2
- @%append $(LINK_ARG) library '$(LIBSSH2_ROOT)/win32/libssh2.lib'
-!endif
-!ifdef %use_ssl
- @%append $(LINK_ARG) library '$(OPENSSL_ROOT)/out32/libeay32.lib'
- @%append $(LINK_ARG) library '$(OPENSSL_ROOT)/out32/ssleay32.lib'
-!endif
-!ifdef %use_ares
- @%append $(LINK_ARG) library '$(ARES_ROOT)/cares.lib'
-!endif
-!ifdef %use_winidn
-! if $(__VERSION__) > 1290
- @%append $(LINK_ARG) library normaliz.lib
-! else
- @%append $(LINK_ARG) import '_IdnToAscii@20' 'NORMALIZ.DLL'.'IdnToAscii'
- @%append $(LINK_ARG) import '_IdnToUnicode@20' 'NORMALIZ.DLL'.'IdnToUnicode'
-! endif
-!endif
- $(LD) name $^@ @$(LINK_ARG)
-
-$(LIBNAME).lib: $(OBJS_STAT)
- %create $(LIB_ARG)
- @for %f in ($<) do @%append $(LIB_ARG) +- %f
- $(AR) -q -b -c -pa $^@ @$(LIB_ARG)
-
-$(RESOURCE): libcurl.rc
- $(RC) $(DEBUG) -q -r -zm -bt=nt -I"../include" $(SYS_INCL) $[@ -fo=$^@
-
-.c{$(OBJ_DYN)}.obj:
- $(CC) $(CFLAGS) -bd -br $[@ -fo=$^@
-
-.c{$(OBJ_STAT)}.obj:
- $(CC) $(CFLAGS) -DCURL_STATICLIB $[@ -fo=$^@
diff --git a/lib/Makefile.am b/lib/Makefile.am
index ada137ffe..57d1ea4d5 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -25,7 +25,7 @@ ED_1 = Makefile.m32 config-win32.h config-win32ce.h
ED_2 = config-plan9.h config-riscos.h config-mac.h curl_config.h.in
ED_3 = makefile.dj config-dos.h libgnurl.plist libcurl.rc config-amigaos.h
ED_4 = makefile.amiga Makefile.netware nwlib.c nwos.c config-win32ce.h
-ED_5 = config-os400.h setup-os400.h config-symbian.h Makefile.Watcom
+ED_5 = config-os400.h setup-os400.h
ED_6 = config-tpf.h mk-ca-bundle.pl mk-ca-bundle.vbs $(CMAKE_DIST)
ED_7 = firefox-db2pem.sh config-vxworks.h Makefile.vxworks checksrc.pl setup-win32.h
@@ -62,7 +62,7 @@ endif
# Prevent LIBS from being used for all link targets
LIBS = $(BLANK_AT_MAKETIME)
-VERSIONINFO=-version-info 10:0:6
+VERSIONINFO=-version-info 11:0:7
# This flag accepts an argument of the form current[:revision[:age]]. So,
# passing -version-info 3:12:1 sets current to 3, revision to 12, and age to
# 1.
@@ -148,3 +148,6 @@ TIDY:=clang-tidy
tidy:
$(TIDY) $(CSOURCES) $(TIDYFLAGS) -- $(AM_CPPFLAGS) $(CPPFLAGS) -DHAVE_CONFIG_H
+
+optiontable:
+ perl optiontable.pl < $(top_srcdir)/include/curl/curl.h > easyoptions.c
diff --git a/lib/Makefile.inc b/lib/Makefile.inc
index ae3f961cf..6d35704c0 100644
--- a/lib/Makefile.inc
+++ b/lib/Makefile.inc
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -56,19 +56,19 @@ LIB_CFILES = altsvc.c amigaos.c asyn-ares.c asyn-thread.c base64.c \
http_ntlm.c http_proxy.c idn_win32.c if2ip.c imap.c inet_ntop.c inet_pton.c \
krb5.c ldap.c llist.c md4.c md5.c memdebug.c mime.c mprintf.c mqtt.c \
multi.c netrc.c non-ascii.c nonblock.c openldap.c parsedate.c pingpong.c \
- pop3.c progress.c psl.c doh.c rand.c rename.c rtsp.c security.c select.c \
+ pop3.c progress.c psl.c doh.c rand.c rename.c rtsp.c select.c \
sendf.c setopt.c sha256.c share.c slist.c smb.c smtp.c socketpair.c socks.c \
socks_gssapi.c socks_sspi.c speedcheck.c splay.c strcase.c strdup.c \
strerror.c strtok.c strtoofft.c system_win32.c telnet.c tftp.c timeval.c \
transfer.c urlapi.c version.c warnless.c wildcard.c x509asn1.c dynbuf.c \
- version_win32.c
+ version_win32.c easyoptions.c easygetopt.c hsts.c
LIB_HFILES = altsvc.h amigaos.h arpa_telnet.h asyn.h conncache.h connect.h \
content_encoding.h cookie.h curl_addrinfo.h curl_base64.h curl_ctype.h \
curl_des.h curl_endian.h curl_fnmatch.h curl_get_line.h curl_gethostname.h \
curl_gssapi.h curl_hmac.h curl_ldap.h curl_md4.h curl_md5.h curl_memory.h \
curl_memrchr.h curl_multibyte.h curl_ntlm_core.h curl_ntlm_wb.h curl_path.h \
- curl_printf.h curl_range.h curl_rtmp.h curl_sasl.h curl_sec.h curl_setup.h \
+ curl_printf.h curl_range.h curl_rtmp.h curl_sasl.h curl_krb5.h curl_setup.h \
curl_setup_once.h curl_sha256.h curl_sspi.h curl_threads.h curlx.h dict.h \
dotdot.h easyif.h escape.h file.h fileinfo.h formdata.h ftp.h url.h \
ftplistparser.h getinfo.h gopher.h hash.h hostcheck.h hostip.h http.h \
@@ -80,7 +80,7 @@ LIB_HFILES = altsvc.h amigaos.h arpa_telnet.h asyn.h conncache.h connect.h \
smb.h smtp.h sockaddr.h socketpair.h socks.h speedcheck.h splay.h strcase.h \
strdup.h strerror.h strtok.h strtoofft.h system_win32.h telnet.h tftp.h \
timeval.h transfer.h urlapi-int.h urldata.h warnless.h wildcard.h \
- x509asn1.h dynbuf.h version_win32.h
+ x509asn1.h dynbuf.h version_win32.h easyoptions.h hsts.h
LIB_RCFILES = libcurl.rc
diff --git a/lib/Makefile.m32 b/lib/Makefile.m32
index 02b31106c..d23eeead3 100644
--- a/lib/Makefile.m32
+++ b/lib/Makefile.m32
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -77,6 +77,14 @@ endif
ifndef NGHTTP2_PATH
NGHTTP2_PATH = ../../nghttp2-1.0.0
endif
+# Edit the path below to point to the base of your nghttp3 package.
+ifndef NGHTTP3_PATH
+NGHTTP3_PATH = ../../nghttp3-1.0.0
+endif
+# Edit the path below to point to the base of your ngtcp2 package.
+ifndef NGTCP2_PATH
+NGTCP2_PATH = ../../ngtcp2-1.0.0
+endif
PROOT = ..
@@ -212,6 +220,15 @@ endif
ifeq ($(findstring -nghttp2,$(CFG)),-nghttp2)
NGHTTP2 = 1
endif
+ifeq ($(findstring -nghttp3,$(CFG)),-nghttp3)
+NGHTTP3 = 1
+endif
+ifeq ($(findstring -ngtcp2,$(CFG)),-ngtcp2)
+NGTCP2 = 1
+endif
+ifeq ($(findstring -unicode,$(CFG)),-unicode)
+UNICODE = 1
+endif
INCLUDES = -I. -I../include
CFLAGS += -DBUILDING_LIBCURL
@@ -220,6 +237,9 @@ ifdef SSL
CFLAGS += -DCURL_WITH_MULTI_SSL
endif
endif
+ifdef UNICODE
+ CFLAGS += -DUNICODE -D_UNICODE
+endif
ifdef SYNC
CFLAGS += -DUSE_SYNC_DNS
@@ -252,6 +272,17 @@ ifdef SSH2
endif
endif
ifdef SSL
+ ifdef NGHTTP3
+ INCLUDES += -I"$(NGHTTP3_PATH)/include"
+ CFLAGS += -DUSE_NGHTTP3
+ DLL_LIBS += -L"$(NGHTTP3_PATH)/lib" -lnghttp3
+ ifdef NGTCP2
+ INCLUDES += -I"$(NGTCP2_PATH)/include"
+ CFLAGS += -DUSE_NGTCP2
+ DLL_LIBS += -L"$(NGTCP2_PATH)/lib" -lngtcp2 -lngtcp2_crypto_openssl
+ endif
+ endif
+
ifndef OPENSSL_INCLUDE
ifeq "$(wildcard $(OPENSSL_PATH)/outinc)" "$(OPENSSL_PATH)/outinc"
OPENSSL_INCLUDE = $(OPENSSL_PATH)/outinc
@@ -298,7 +329,12 @@ endif
ifdef ZSTD
INCLUDES += -I"$(ZSTD_PATH)/include"
CFLAGS += -DHAVE_ZSTD
- DLL_LIBS += -L"$(ZSTD_PATH)/lib" -lzstd
+ DLL_LIBS += -L"$(ZSTD_PATH)/lib"
+ ifdef ZSTD_LIBS
+ DLL_LIBS += $(ZSTD_LIBS)
+ else
+ DLL_LIBS += -lzstd
+ endif
endif
ifdef BROTLI
INCLUDES += -I"$(BROTLI_PATH)/include"
diff --git a/lib/Makefile.netware b/lib/Makefile.netware
index 625f88df1..4539b99f2 100644
--- a/lib/Makefile.netware
+++ b/lib/Makefile.netware
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -82,7 +82,7 @@ endif
TARGET = libcurl
VERSION = $(LIBCURL_VERSION)
COPYR = Copyright (C) $(LIBCURL_COPYRIGHT_STR)
-DESCR = curl libcurl $(LIBCURL_VERSION_STR) ($(LIBARCH)) - https://curl.haxx.se
+DESCR = curl libcurl $(LIBCURL_VERSION_STR) ($(LIBARCH)) - https://curl.se
MTSAFE = YES
STACK = 64000
SCREEN = none
@@ -481,7 +481,7 @@ curl_config.h: Makefile.netware
@echo $(DL)#error This $(notdir $@) is created for NetWare platform!$(DL) >> $@
@echo $(DL)#endif$(DL) >> $@
@echo $(DL)#define VERSION "$(LIBCURL_VERSION_STR)"$(DL) >> $@
- @echo $(DL)#define PACKAGE_BUGREPORT "a suitable curl mailing list => https://curl.haxx.se/mail/"$(DL) >> $@
+ @echo $(DL)#define PACKAGE_BUGREPORT "a suitable curl mailing list => https://curl.se/mail/"$(DL) >> $@
ifeq ($(LIBARCH),CLIB)
@echo $(DL)#define OS "i586-pc-clib-NetWare"$(DL) >> $@
@echo $(DL)#define NETDB_USE_INTERNET 1$(DL) >> $@
diff --git a/lib/Makefile.vxworks b/lib/Makefile.vxworks
index ada87fbd3..91f9d6149 100644
--- a/lib/Makefile.vxworks
+++ b/lib/Makefile.vxworks
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/lib/altsvc.c b/lib/altsvc.c
index b1c5db833..d0aa00b80 100644
--- a/lib/altsvc.c
+++ b/lib/altsvc.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -25,7 +25,7 @@
*/
#include "curl_setup.h"
-#if !defined(CURL_DISABLE_HTTP) && defined(USE_ALTSVC)
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_ALTSVC)
#include <gnurl/curl.h>
#include "urldata.h"
#include "altsvc.h"
@@ -302,11 +302,12 @@ CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl)
* Curl_altsvc_cleanup() frees an altsvc cache instance and all associated
* resources.
*/
-void Curl_altsvc_cleanup(struct altsvcinfo *altsvc)
+void Curl_altsvc_cleanup(struct altsvcinfo **altsvcp)
{
- struct curl_llist_element *e;
- struct curl_llist_element *n;
- if(altsvc) {
+ struct Curl_llist_element *e;
+ struct Curl_llist_element *n;
+ if(*altsvcp) {
+ struct altsvcinfo *altsvc = *altsvcp;
for(e = altsvc->list.head; e; e = n) {
struct altsvc *as = e->ptr;
n = e->next;
@@ -314,6 +315,7 @@ void Curl_altsvc_cleanup(struct altsvcinfo *altsvc)
}
free(altsvc->filename);
free(altsvc);
+ *altsvcp = NULL; /* clear the pointer */
}
}
@@ -323,8 +325,8 @@ void Curl_altsvc_cleanup(struct altsvcinfo *altsvc)
CURLcode Curl_altsvc_save(struct Curl_easy *data,
struct altsvcinfo *altsvc, const char *file)
{
- struct curl_llist_element *e;
- struct curl_llist_element *n;
+ struct Curl_llist_element *e;
+ struct Curl_llist_element *n;
CURLcode result = CURLE_OK;
FILE *out;
char *tempstore;
@@ -353,7 +355,7 @@ CURLcode Curl_altsvc_save(struct Curl_easy *data,
if(!out)
result = CURLE_WRITE_ERROR;
else {
- fputs("# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html\n"
+ fputs("# Your alt-svc cache. https://curl.se/docs/alt-svc.html\n"
"# This file was generated by libcurl! Edit at your own risk.\n",
out);
for(e = altsvc->list.head; e; e = n) {
@@ -399,8 +401,8 @@ static CURLcode getalnum(const char **ptr, char *alpnbuf, size_t buflen)
static void altsvc_flush(struct altsvcinfo *asi, enum alpnid srcalpnid,
const char *srchost, unsigned short srcport)
{
- struct curl_llist_element *e;
- struct curl_llist_element *n;
+ struct Curl_llist_element *e;
+ struct Curl_llist_element *n;
for(e = asi->list.head; e; e = n) {
struct altsvc *as = e->ptr;
n = e->next;
@@ -449,12 +451,14 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
{
const char *p = value;
size_t len;
- enum alpnid dstalpnid = srcalpnid; /* the same by default */
char namebuf[MAX_ALTSVC_HOSTLEN] = "";
char alpnbuf[MAX_ALTSVC_ALPNLEN] = "";
struct altsvc *as;
unsigned short dstport = srcport; /* the same by default */
CURLcode result = getalnum(&p, alpnbuf, sizeof(alpnbuf));
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+ (void)data;
+#endif
if(result) {
infof(data, "Excessive alt-svc header, ignoring...\n");
return CURLE_OK;
@@ -473,7 +477,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
do {
if(*p == '=') {
/* [protocol]="[host][:port]" */
- dstalpnid = alpn2alpnid(alpnbuf);
+ enum alpnid dstalpnid = alpn2alpnid(alpnbuf); /* the same by default */
p++;
if(*p == '\"') {
const char *dsthost = "";
@@ -612,8 +616,8 @@ bool Curl_altsvc_lookup(struct altsvcinfo *asi,
struct altsvc **dstentry,
const int versions) /* one or more bits */
{
- struct curl_llist_element *e;
- struct curl_llist_element *n;
+ struct Curl_llist_element *e;
+ struct Curl_llist_element *n;
time_t now = time(NULL);
DEBUGASSERT(asi);
DEBUGASSERT(srchost);
@@ -640,4 +644,4 @@ bool Curl_altsvc_lookup(struct altsvcinfo *asi,
return FALSE;
}
-#endif /* CURL_DISABLE_HTTP || USE_ALTSVC */
+#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_ALTSVC */
diff --git a/lib/altsvc.h b/lib/altsvc.h
index cdf137aff..bf368c9fa 100644
--- a/lib/altsvc.h
+++ b/lib/altsvc.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -23,7 +23,7 @@
***************************************************************************/
#include "curl_setup.h"
-#if !defined(CURL_DISABLE_HTTP) && defined(USE_ALTSVC)
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_ALTSVC)
#include <gnurl/curl.h>
#include "llist.h"
@@ -46,12 +46,12 @@ struct altsvc {
time_t expires;
bool persist;
int prio;
- struct curl_llist_element node;
+ struct Curl_llist_element node;
};
struct altsvcinfo {
char *filename;
- struct curl_llist list; /* list of entries */
+ struct Curl_llist list; /* list of entries */
long flags; /* the publicly set bitmask */
};
@@ -61,7 +61,7 @@ CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file);
CURLcode Curl_altsvc_save(struct Curl_easy *data,
struct altsvcinfo *asi, const char *file);
CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl);
-void Curl_altsvc_cleanup(struct altsvcinfo *altsvc);
+void Curl_altsvc_cleanup(struct altsvcinfo **altsvc);
CURLcode Curl_altsvc_parse(struct Curl_easy *data,
struct altsvcinfo *altsvc, const char *value,
enum alpnid srcalpn, const char *srchost,
@@ -74,5 +74,6 @@ bool Curl_altsvc_lookup(struct altsvcinfo *asi,
#else
/* disabled */
#define Curl_altsvc_save(a,b,c)
-#endif /* CURL_DISABLE_HTTP || USE_ALTSVC */
+#define Curl_altsvc_cleanup(x)
+#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_ALTSVC */
#endif /* HEADER_CURL_ALTSVC_H */
diff --git a/lib/amigaos.c b/lib/amigaos.c
index cf44bdc8d..d3b00d908 100644
--- a/lib/amigaos.c
+++ b/lib/amigaos.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/amigaos.h b/lib/amigaos.h
index c776c9c9b..02e5bb546 100644
--- a/lib/amigaos.h
+++ b/lib/amigaos.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/arpa_telnet.h b/lib/arpa_telnet.h
index 232680e7d..cbe31de5a 100644
--- a/lib/arpa_telnet.h
+++ b/lib/arpa_telnet.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/asyn-ares.c b/lib/asyn-ares.c
index e65150744..174757188 100644
--- a/lib/asyn-ares.c
+++ b/lib/asyn-ares.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -67,8 +67,8 @@
#include "select.h"
#include "progress.h"
-# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
- (defined(WIN32) || defined(__SYMBIAN32__))
+# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
+ defined(WIN32)
# define CARES_STATICLIB
# endif
# include <ares.h>
@@ -85,7 +85,7 @@
#include "curl_memory.h"
#include "memdebug.h"
-struct ResolverResults {
+struct thread_data {
int num_pending; /* number of ares_gethostbyname() requests */
struct Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares
parts */
@@ -229,8 +229,8 @@ static void destroy_async_data(struct Curl_async *async)
{
free(async->hostname);
- if(async->os_specific) {
- struct ResolverResults *res = (struct ResolverResults *)async->os_specific;
+ if(async->tdata) {
+ struct thread_data *res = async->tdata;
if(res) {
if(res->temp_ai) {
Curl_freeaddrinfo(res->temp_ai);
@@ -238,7 +238,7 @@ static void destroy_async_data(struct Curl_async *async)
}
free(res);
}
- async->os_specific = NULL;
+ async->tdata = NULL;
}
async->hostname = NULL;
@@ -349,8 +349,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
struct Curl_dns_entry **dns)
{
struct Curl_easy *data = conn->data;
- struct ResolverResults *res = (struct ResolverResults *)
- conn->async.os_specific;
+ struct thread_data *res = conn->async.tdata;
CURLcode result = CURLE_OK;
DEBUGASSERT(dns);
@@ -498,7 +497,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
}
/* Connects results to the list */
-static void compound_results(struct ResolverResults *res,
+static void compound_results(struct thread_data *res,
struct Curl_addrinfo *ai)
{
struct Curl_addrinfo *ai_tail;
@@ -527,7 +526,7 @@ static void query_completed_cb(void *arg, /* (struct connectdata *) */
struct hostent *hostent)
{
struct connectdata *conn = (struct connectdata *)arg;
- struct ResolverResults *res;
+ struct thread_data *res;
#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
(void)timeouts; /* ignored */
@@ -538,7 +537,7 @@ static void query_completed_cb(void *arg, /* (struct connectdata *) */
be valid so only defer it when we know the 'status' says its fine! */
return;
- res = (struct ResolverResults *)conn->async.os_specific;
+ res = conn->async.tdata;
if(res) {
res->num_pending--;
@@ -653,20 +652,20 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
bufp = strdup(hostname);
if(bufp) {
- struct ResolverResults *res = NULL;
+ struct thread_data *res = NULL;
free(conn->async.hostname);
conn->async.hostname = bufp;
conn->async.port = port;
conn->async.done = FALSE; /* not done */
conn->async.status = 0; /* clear */
conn->async.dns = NULL; /* clear */
- res = calloc(sizeof(struct ResolverResults), 1);
+ res = calloc(sizeof(struct thread_data), 1);
if(!res) {
free(conn->async.hostname);
conn->async.hostname = NULL;
return NULL;
}
- conn->async.os_specific = res;
+ conn->async.tdata = res;
/* initial status - failed */
res->last_status = ARES_ENOTFOUND;
diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c
index a60f4f066..7c8598274 100644
--- a/lib/asyn-thread.c
+++ b/lib/asyn-thread.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -185,7 +185,7 @@ struct thread_data {
static struct thread_sync_data *conn_thread_sync_data(struct connectdata *conn)
{
- return &(((struct thread_data *)conn->async.os_specific)->tsd);
+ return &(conn->async.tdata->tsd);
}
/* Destroy resolver thread synchronization data */
@@ -294,7 +294,7 @@ static int getaddrinfo_complete(struct connectdata *conn)
*/
static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg)
{
- struct thread_sync_data *tsd = (struct thread_sync_data*)arg;
+ struct thread_sync_data *tsd = (struct thread_sync_data *)arg;
struct thread_data *td = tsd->td;
char service[12];
int rc;
@@ -380,8 +380,8 @@ static unsigned int CURL_STDCALL gethostbyname_thread(void *arg)
*/
static void destroy_async_data(struct Curl_async *async)
{
- if(async->os_specific) {
- struct thread_data *td = (struct thread_data*) async->os_specific;
+ if(async->tdata) {
+ struct thread_data *td = async->tdata;
int done;
#ifdef USE_SOCKETPAIR
curl_socket_t sock_rd = td->tsd.sock_pair[0];
@@ -406,7 +406,7 @@ static void destroy_async_data(struct Curl_async *async)
destroy_thread_sync_data(&td->tsd);
- free(async->os_specific);
+ free(async->tdata);
}
#ifdef USE_SOCKETPAIR
/*
@@ -418,7 +418,7 @@ static void destroy_async_data(struct Curl_async *async)
sclose(sock_rd);
#endif
}
- async->os_specific = NULL;
+ async->tdata = NULL;
free(async->hostname);
async->hostname = NULL;
@@ -437,7 +437,7 @@ static bool init_resolve_thread(struct connectdata *conn,
struct thread_data *td = calloc(1, sizeof(struct thread_data));
int err = ENOMEM;
- conn->async.os_specific = (void *)td;
+ conn->async.tdata = td;
if(!td)
goto errno_exit;
@@ -448,7 +448,7 @@ static bool init_resolve_thread(struct connectdata *conn,
td->thread_hnd = curl_thread_t_null;
if(!init_thread_sync_data(td, hostname, port, hints)) {
- conn->async.os_specific = NULL;
+ conn->async.tdata = NULL;
free(td);
goto errno_exit;
}
@@ -519,7 +519,7 @@ static CURLcode thread_wait_resolv(struct connectdata *conn,
struct Curl_dns_entry **entry,
bool report)
{
- struct thread_data *td = (struct thread_data*) conn->async.os_specific;
+ struct thread_data *td = conn->async.tdata;
CURLcode result = CURLE_OK;
DEBUGASSERT(conn && td);
@@ -557,7 +557,7 @@ static CURLcode thread_wait_resolv(struct connectdata *conn,
*/
void Curl_resolver_kill(struct connectdata *conn)
{
- struct thread_data *td = (struct thread_data*) conn->async.os_specific;
+ struct thread_data *td = conn->async.tdata;
/* If we're still resolving, we must wait for the threads to fully clean up,
unfortunately. Otherwise, we can simply cancel to clean up any resolver
@@ -596,7 +596,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
struct Curl_dns_entry **entry)
{
struct Curl_easy *data = conn->data;
- struct thread_data *td = (struct thread_data*) conn->async.os_specific;
+ struct thread_data *td = conn->async.tdata;
int done = 0;
DEBUGASSERT(entry);
@@ -656,7 +656,7 @@ int Curl_resolver_getsock(struct connectdata *conn,
struct Curl_easy *data = conn->data;
struct resdata *reslv = (struct resdata *)data->state.resolver;
#ifdef USE_SOCKETPAIR
- struct thread_data *td = (struct thread_data*)conn->async.os_specific;
+ struct thread_data *td = conn->async.tdata;
#else
(void)socks;
#endif
diff --git a/lib/asyn.h b/lib/asyn.h
index bd3c3c123..73a9b7268 100644
--- a/lib/asyn.h
+++ b/lib/asyn.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/base64.c b/lib/base64.c
index 643cef625..be6f163dc 100644
--- a/lib/base64.c
+++ b/lib/base64.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -26,6 +26,9 @@
#if !defined(CURL_DISABLE_HTTP_AUTH) || defined(USE_SSH) || \
!defined(CURL_DISABLE_LDAP) || \
+ !defined(CURL_DISABLE_SMTP) || \
+ !defined(CURL_DISABLE_POP3) || \
+ !defined(CURL_DISABLE_IMAP) || \
!defined(CURL_DISABLE_DOH) || defined(USE_SSL)
#include "urldata.h" /* for the Curl_easy definition */
diff --git a/lib/checksrc.pl b/lib/checksrc.pl
index 498da94bb..13f86ecd5 100755
--- a/lib/checksrc.pl
+++ b/lib/checksrc.pl
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -52,7 +52,7 @@ my %warnings_extended = (
my %warnings = (
'LONGLINE' => "Line longer than $max_column",
'TABS' => 'TAB characters not allowed',
- 'TRAILINGSPACE' => 'Trailing white space on the line',
+ 'TRAILINGSPACE' => 'Trailing whitespace on the line',
'CPPCOMMENTS' => '// comment detected',
'SPACEBEFOREPAREN' => 'space before an open parenthesis',
'SPACEAFTERPAREN' => 'space after open parenthesis',
@@ -82,6 +82,10 @@ my %warnings = (
'SNPRINTF' => 'use of snprintf',
'ONELINECONDITION' => 'conditional block on the same line as the if()',
'TYPEDEFSTRUCT' => 'typedefed struct',
+ 'DOBRACE' => 'A single space between do and open brace',
+ 'BRACEWHILE' => 'A single space between open brace and while',
+ 'EXCLAMATIONSPACE' => 'Whitespace after exclamation mark in expression',
+ 'EMPTYLINEBRACE' => 'Empty line before the open brace',
);
sub readskiplist {
@@ -397,7 +401,7 @@ sub scanfile {
checkwarn("TABS",
$line, length($1), $file, $l, "Contains TAB character", 1);
}
- # detect trailing white space
+ # detect trailing whitespace
if($l =~ /^(.*)[ \t]+\z/) {
checkwarn("TRAILINGSPACE",
$line, length($1), $file, $l, "Trailing whitespace");
@@ -439,7 +443,7 @@ sub scanfile {
# crude attempt to detect // comments without too many false
# positives
- if($l =~ /^([^"\*]*)[^:"]\/\//) {
+ if($l =~ /^(([^"\*]*)[^:"]|)\/\//) {
checkwarn("CPPCOMMENTS",
$line, length($1), $file, $l, "\/\/ comment");
}
@@ -468,6 +472,14 @@ sub scanfile {
}
}
+ # check spaces in 'do {'
+ if($nostr =~ /^( *)do( *)\{/ && length($2) != 1) {
+ checkwarn("DOBRACE", $line, length($1) + 2, $file, $l, "one space after do before brace");
+ }
+ # check spaces in 'do {'
+ elsif($nostr =~ /^( *)\}( *)while/ && length($2) != 1) {
+ checkwarn("BRACEWHILE", $line, length($1) + 2, $file, $l, "one space between brace and while");
+ }
if($nostr =~ /^((.*\s)(if) *\()(.*)\)(.*)/) {
my $pos = length($1);
my $postparen = $5;
@@ -583,6 +595,11 @@ sub scanfile {
checkwarn("PARENBRACE",
$line, length($1)+1, $file, $l, "missing space after close paren");
}
+ # check for "^{" with an empty line before it
+ if(($l =~ /^\{/) && ($prevl =~ /^[ \t]*\z/)) {
+ checkwarn("EMPTYLINEBRACE",
+ $line, 0, $file, $l, "empty line before open brace");
+ }
# check for space before the semicolon last in a line
if($l =~ /^(.*[^ ].*) ;$/) {
@@ -715,6 +732,12 @@ sub scanfile {
"typedef'ed struct");
}
+ if($nostr =~ /(.*)! +(\w|\()/) {
+ checkwarn("EXCLAMATIONSPACE",
+ $line, length($1)+1, $file, $ol,
+ "space after exclamation mark");
+ }
+
# check for more than one consecutive space before open brace or
# question mark. Skip lines containing strings since they make it hard
# due to artificially getting multiple spaces
diff --git a/lib/config-amigaos.h b/lib/config-amigaos.h
index 12a87cf29..3c9d76ef3 100644
--- a/lib/config-amigaos.h
+++ b/lib/config-amigaos.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -96,7 +96,7 @@
#define OS "AmigaOS"
#define PACKAGE "curl"
-#define PACKAGE_BUGREPORT "a suitable mailing list: https://curl.haxx.se/mail/"
+#define PACKAGE_BUGREPORT "a suitable mailing list: https://curl.se/mail/"
#define PACKAGE_NAME "curl"
#define PACKAGE_STRING "curl -"
#define PACKAGE_TARNAME "curl"
diff --git a/lib/config-dos.h b/lib/config-dos.h
index 349e75639..50816ac75 100644
--- a/lib/config-dos.h
+++ b/lib/config-dos.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/config-mac.h b/lib/config-mac.h
index 14b98fe57..4e610562f 100644
--- a/lib/config-mac.h
+++ b/lib/config-mac.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/config-os400.h b/lib/config-os400.h
index 7beb81faf..b8676113d 100644
--- a/lib/config-os400.h
+++ b/lib/config-os400.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -422,9 +422,6 @@
/* Define if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME
-/* Define to enable alt-svc support (experimental) */
-#undef USE_ALTSVC
-
/* Define to enable HTTP3 support (experimental, requires NGTCP2 or QUICHE) */
#undef ENABLE_QUIC
diff --git a/lib/config-plan9.h b/lib/config-plan9.h
index 41440a14e..cc8adde72 100644
--- a/lib/config-plan9.h
+++ b/lib/config-plan9.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -33,7 +33,7 @@
#define OS "plan9"
#define PACKAGE "curl"
#define PACKAGE_NAME "curl"
-#define PACKAGE_BUGREPORT "a suitable mailing list: https://curl.haxx.se/mail/"
+#define PACKAGE_BUGREPORT "a suitable mailing list: https://curl.se/mail/"
#define PACKAGE_STRING "curl -"
#define PACKAGE_TARNAME "curl"
#define PACKAGE_VERSION "-"
diff --git a/lib/config-riscos.h b/lib/config-riscos.h
index 0ddf487e8..9b5f8da92 100644
--- a/lib/config-riscos.h
+++ b/lib/config-riscos.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/config-symbian.h b/lib/config-symbian.h
deleted file mode 100644
index 7f17dce25..000000000
--- a/lib/config-symbian.h
+++ /dev/null
@@ -1,793 +0,0 @@
-#ifndef HEADER_CURL_CONFIG_SYMBIAN_H
-#define HEADER_CURL_CONFIG_SYMBIAN_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-/* ================================================================ */
-/* Hand crafted config file for Symbian */
-/* ================================================================ */
-
-/* Location of default ca bundle */
-/* #define CURL_CA_BUNDLE "/etc/pki/tls/certs/ca-bundle.crt"*/
-
-/* Location of default ca path */
-/* #undef CURL_CA_PATH */
-
-/* to disable cookies support */
-/* #undef CURL_DISABLE_COOKIES */
-
-/* to disable cryptographic authentication */
-/* #undef CURL_DISABLE_CRYPTO_AUTH */
-
-/* to disable DICT */
-/* #undef CURL_DISABLE_DICT */
-
-/* to disable FILE */
-/* #undef CURL_DISABLE_FILE */
-
-/* to disable FTP */
-/* #undef CURL_DISABLE_FTP */
-
-/* to disable HTTP */
-/* #undef CURL_DISABLE_HTTP */
-
-/* to disable LDAP */
-#define CURL_DISABLE_LDAP 1
-
-/* to disable LDAPS */
-#define CURL_DISABLE_LDAPS 1
-
-/* to disable TELNET */
-/* #undef CURL_DISABLE_TELNET */
-
-/* to disable TFTP */
-/* #undef CURL_DISABLE_TFTP */
-
-/* to disable verbose strings */
-/* #define CURL_DISABLE_VERBOSE_STRINGS 1*/
-
-/* Definition to make a library symbol externally visible. */
-/* #undef CURL_EXTERN_SYMBOL */
-
-/* Use Windows LDAP implementation */
-/* #undef USE_WIN32_LDAP */
-
-/* your Entropy Gathering Daemon socket pathname */
-/* #undef EGD_SOCKET */
-
-/* Define if you want to enable IPv6 support */
-#define ENABLE_IPV6 1
-
-/* Define if struct sockaddr_in6 has the sin6_scope_id member */
-#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
-
-/* Define to the type qualifier of arg 1 for getnameinfo. */
-#define GETNAMEINFO_QUAL_ARG1 const
-
-/* Define to the type of arg 1 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
-
-/* Define to the type of arg 2 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG2 socklen_t
-
-/* Define to the type of args 4 and 6 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG46 size_t
-
-/* Define to the type of arg 7 for getnameinfo. */
-#define GETNAMEINFO_TYPE_ARG7 int
-
-/* Define to 1 if you have the <alloca.h> header file. */
-/*#define HAVE_ALLOCA_H 1*/
-
-/* Define to 1 if you have the <arpa/inet.h> header file. */
-#define HAVE_ARPA_INET_H 1
-
-/* Define to 1 if you have the <arpa/tftp.h> header file. */
-/*#define HAVE_ARPA_TFTP_H 1*/
-
-/* Define to 1 if you have the <assert.h> header file. */
-#define HAVE_ASSERT_H 1
-
-/* Define to 1 if you have the `basename' function. */
-/*#define HAVE_BASENAME 1*/
-
-/* Define to 1 if bool is an available type. */
-/*#define HAVE_BOOL_T 1*/
-
-/* Define to 1 if you have the `closesocket' function. */
-/* #undef HAVE_CLOSESOCKET */
-
-/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
-/*#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1*/
-
-/* Define to 1 if you have the <crypto.h> header file. */
-/* #undef HAVE_CRYPTO_H */
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the <errno.h> header file. */
-#define HAVE_ERRNO_H 1
-
-/* Define to 1 if you have the <err.h> header file. */
-#define HAVE_ERR_H 1
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define to 1 if you have the fcntl function. */
-#define HAVE_FCNTL 1
-
-/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
-#define HAVE_FCNTL_O_NONBLOCK 1
-
-/* Define to 1 if you have the `fork' function. */
-/*#define HAVE_FORK 1*/
-
-/* Define to 1 if you have the `ftruncate' function. */
-#define HAVE_FTRUNCATE 1
-
-/* Define if getaddrinfo exists and works */
-#define HAVE_GETADDRINFO 1
-
-/* Define to 1 if you have the `geteuid' function. */
-#define HAVE_GETEUID 1
-
-/* Define to 1 if you have the `gethostbyaddr' function. */
-#define HAVE_GETHOSTBYADDR 1
-
-/* If you have gethostbyname */
-#define HAVE_GETHOSTBYNAME 1
-
-/* Define to 1 if you have the `gethostbyname_r' function. */
-/* #undef HAVE_GETHOSTBYNAME_R */
-
-/* gethostbyname_r() takes 3 args */
-/* #undef HAVE_GETHOSTBYNAME_R_3 */
-
-/* gethostbyname_r() takes 5 args */
-/* #undef HAVE_GETHOSTBYNAME_R_5 */
-
-/* gethostbyname_r() takes 6 args */
-/* #undef HAVE_GETHOSTBYNAME_R_6 */
-
-/* Define to 1 if you have the getnameinfo function. */
-#define HAVE_GETNAMEINFO 1
-
-/* Define to 1 if you have the `getpass_r' function. */
-/* #undef HAVE_GETPASS_R */
-
-/* Define to 1 if you have the `getppid' function. */
-#define HAVE_GETPPID 1
-
-/* Define to 1 if you have the `getprotobyname' function. */
-#define HAVE_GETPROTOBYNAME 1
-
-/* Define to 1 if you have the `getpwuid' function. */
-#define HAVE_GETPWUID 1
-
-/* Define to 1 if you have the `getrlimit' function. */
-/*#define HAVE_GETRLIMIT 1*/
-
-/* Define to 1 if you have the `gettimeofday' function. */
-#define HAVE_GETTIMEOFDAY 1
-
-/* we have a glibc-style strerror_r() */
-/* #undef HAVE_GLIBC_STRERROR_R */
-
-/* Define to 1 if you have the `gmtime_r' function. */
-#define HAVE_GMTIME_R 1
-
-/* if you have the gssapi libraries */
-/* #undef HAVE_GSSAPI */
-
-/* Define to 1 if you have the <gssapi/gssapi_generic.h> header file. */
-/* #undef HAVE_GSSAPI_GSSAPI_GENERIC_H */
-
-/* Define to 1 if you have the <gssapi/gssapi.h> header file. */
-/* #undef HAVE_GSSAPI_GSSAPI_H */
-
-/* Define to 1 if you have the <gssapi/gssapi_krb5.h> header file. */
-/* #undef HAVE_GSSAPI_GSSAPI_KRB5_H */
-
-/* if you have the GNU gssapi libraries */
-/* #undef HAVE_GSSGNU */
-
-/* if you have the Heimdal gssapi libraries */
-/* #undef HAVE_GSSHEIMDAL */
-
-/* if you have the MIT gssapi libraries */
-/* #undef HAVE_GSSMIT */
-
-/* Define to 1 if you have the `idna_strerror' function. */
-/*#define HAVE_IDNA_STRERROR 1*/
-
-/* Define to 1 if you have the `idn_free' function. */
-/*#define HAVE_IDN_FREE 1*/
-
-/* Define to 1 if you have the <idn-free.h> header file. */
-/*#define HAVE_IDN_FREE_H 1*/
-
-/* Define to 1 if you have the `inet_addr' function. */
-/*#define HAVE_INET_ADDR 1*/
-
-/* Define to 1 if you have a IPv6 capable working inet_ntop function. */
-/*#define HAVE_INET_NTOP 1*/
-
-/* Define to 1 if you have a IPv6 capable working inet_pton function. */
-/*#define HAVE_INET_PTON 1*/
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the ioctl function. */
-#define HAVE_IOCTL 1
-
-/* Define to 1 if you have a working ioctl FIONBIO function. */
-#define HAVE_IOCTL_FIONBIO 1
-
-/* Define to 1 if you have the ioctlsocket function. */
-/* #undef HAVE_IOCTLSOCKET */
-
-/* Define to 1 if you have a working ioctlsocket FIONBIO function. */
-/* #undef HAVE_IOCTLSOCKET_FIONBIO */
-
-/* Define to 1 if you have the IoctlSocket camel case function. */
-/* #undef HAVE_IOCTLSOCKET_CAMEL */
-
-/* Define to 1 if you have a working IoctlSocket camel case FIONBIO
- function. */
-/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */
-
-/* Define to 1 if you have the <io.h> header file. */
-/* #undef HAVE_IO_H */
-
-/* if you have the Kerberos4 libraries (including -ldes) */
-/* #undef HAVE_KRB4 */
-
-/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */
-/* #undef HAVE_KRB_GET_OUR_IP_FOR_REALM */
-
-/* Define to 1 if you have the <krb.h> header file. */
-/* #undef HAVE_KRB_H */
-
-/* Define to 1 if you have the lber.h header file. */
-/*#define HAVE_LBER_H 1*/
-
-/* Define to 1 if you have the ldapssl.h header file. */
-/* #undef HAVE_LDAPSSL_H */
-
-/* Define to 1 if you have the ldap.h header file. */
-/*#define HAVE_LDAP_H 1*/
-
-/* Use LDAPS implementation */
-/*#define HAVE_LDAP_SSL 1*/
-
-/* Define to 1 if you have the ldap_ssl.h header file. */
-/* #undef HAVE_LDAP_SSL_H */
-
-/* Define to 1 if you have the `ldap_url_parse' function. */
-/*#define HAVE_LDAP_URL_PARSE 1*/
-
-/* Define to 1 if you have the <libgen.h> header file. */
-/*#define HAVE_LIBGEN_H 1*/
-
-/* Define to 1 if you have the `idn' library (-lidn). */
-/*#define HAVE_LIBIDN 1*/
-
-/* Define to 1 if you have the `resolv' library (-lresolv). */
-/* #undef HAVE_LIBRESOLV */
-
-/* Define to 1 if you have the `resolve' library (-lresolve). */
-/* #undef HAVE_LIBRESOLVE */
-
-/* Define to 1 if you have the `socket' library (-lsocket). */
-/* #undef HAVE_LIBSOCKET */
-
-/* Define to 1 if you have the `ssh2' library (-lssh2). */
-/*#define HAVE_LIBSSH2 1*/
-
-/* Define to 1 if you have the <libssh2.h> header file. */
-/*#define HAVE_LIBSSH2_H 1*/
-
-/* if your compiler supports LL */
-#define HAVE_LL 1
-
-/* Define to 1 if you have the <locale.h> header file. */
-#define HAVE_LOCALE_H 1
-
-/* Define to 1 if you have the `localtime_r' function. */
-#define HAVE_LOCALTIME_R 1
-
-/* Define to 1 if the compiler supports the 'long long' data type. */
-#define HAVE_LONGLONG 1
-
-/* Define to 1 if you have the malloc.h header file. */
-/*#define HAVE_MALLOC_H 1*/
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the MSG_NOSIGNAL flag. */
-/*#define HAVE_MSG_NOSIGNAL 1*/
-
-/* Define to 1 if you have the <netdb.h> header file. */
-#define HAVE_NETDB_H 1
-
-/* Define to 1 if you have the <netinet/in.h> header file. */
-#define HAVE_NETINET_IN_H 1
-
-/* Define to 1 if you have the <netinet/tcp.h> header file. */
-/*#define HAVE_NETINET_TCP_H 1*/
-
-/* Define to 1 if you have the <net/if.h> header file. */
-#define HAVE_NET_IF_H 1
-
-/* Define to 1 if NI_WITHSCOPEID exists and works. */
-/*#define HAVE_NI_WITHSCOPEID 1*/
-
-/* we have no strerror_r() proto */
-/* #undef HAVE_NO_STRERROR_R_DECL */
-
-/* if you have an old MIT gssapi library, lacking GSS_C_NT_HOSTBASED_SERVICE
- */
-/* #undef HAVE_OLD_GSSMIT */
-
-/* Define to 1 if you have the <openssl/crypto.h> header file. */
-/*#define HAVE_OPENSSL_CRYPTO_H 1*/
-
-/* Define to 1 if you have the <openssl/err.h> header file. */
-/*#define HAVE_OPENSSL_ERR_H 1*/
-
-/* Define to 1 if you have the <openssl/pem.h> header file. */
-/*#define HAVE_OPENSSL_PEM_H 1*/
-
-/* Define to 1 if you have the <openssl/pkcs12.h> header file. */
-/*#define HAVE_OPENSSL_PKCS12_H 1*/
-
-/* Define to 1 if you have the <openssl/rsa.h> header file. */
-/*#define HAVE_OPENSSL_RSA_H 1*/
-
-/* Define to 1 if you have the <openssl/ssl.h> header file. */
-/*#define HAVE_OPENSSL_SSL_H 1*/
-
-/* Define to 1 if you have the <openssl/x509.h> header file. */
-/*#define HAVE_OPENSSL_X509_H 1*/
-
-/* Define to 1 if you have the <pem.h> header file. */
-/* #undef HAVE_PEM_H */
-
-/* Define to 1 if you have the `perror' function. */
-#define HAVE_PERROR 1
-
-/* Define to 1 if you have the `pipe' function. */
-#define HAVE_PIPE 1
-
-/* Define to 1 if you have the `poll' function. */
-/*#define HAVE_POLL 1*/
-
-/* If you have a fine poll */
-/*#define HAVE_POLL_FINE 1*/
-
-/* Define to 1 if you have the <poll.h> header file. */
-/*#define HAVE_POLL_H 1*/
-
-/* we have a POSIX-style strerror_r() */
-#define HAVE_POSIX_STRERROR_R 1
-
-/* Define to 1 if you have the <pwd.h> header file. */
-#define HAVE_PWD_H 1
-
-/* Define to 1 if you have the `RAND_egd' function. */
-#define HAVE_RAND_EGD 1
-
-/* Define to 1 if you have the `RAND_screen' function. */
-/* #undef HAVE_RAND_SCREEN */
-
-/* Define to 1 if you have the `RAND_status' function. */
-/*#define HAVE_RAND_STATUS 1*/
-
-/* Define to 1 if you have the recv function. */
-#define HAVE_RECV 1
-
-/* Define to 1 if you have the recvfrom function. */
-#define HAVE_RECVFROM 1
-
-/* Define to 1 if you have the <rsa.h> header file. */
-/* #undef HAVE_RSA_H */
-
-/* Define to 1 if you have the select function. */
-#define HAVE_SELECT 1
-
-/* Define to 1 if you have the send function. */
-#define HAVE_SEND 1
-
-/* Define to 1 if you have the <setjmp.h> header file. */
-#define HAVE_SETJMP_H 1
-
-/* Define to 1 if you have the `setlocale' function. */
-#define HAVE_SETLOCALE 1
-
-/* Define to 1 if you have the `setmode' function. */
-/* #undef HAVE_SETMODE */
-
-/* Define to 1 if you have the `setrlimit' function. */
-/*#define HAVE_SETRLIMIT 1*/
-
-/* Define to 1 if you have the setsockopt function. */
-/* #undef HAVE_SETSOCKOPT */
-
-/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */
-/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */
-
-/* Define to 1 if you have the <sgtty.h> header file. */
-/*#define HAVE_SGTTY_H 1*/
-
-/* Define to 1 if you have the `sigaction' function. */
-/*#define HAVE_SIGACTION 1*/
-
-/* Define to 1 if you have the `siginterrupt' function. */
-/*#define HAVE_SIGINTERRUPT 1*/
-
-/* Define to 1 if you have the `signal' function. */
-/*#define HAVE_SIGNAL 1*/
-
-/* Define to 1 if you have the <signal.h> header file. */
-#define HAVE_SIGNAL_H 1
-
-/* If you have sigsetjmp */
-/*#define HAVE_SIGSETJMP 1*/
-
-/* Define to 1 if sig_atomic_t is an available typedef. */
-/*#define HAVE_SIG_ATOMIC_T 1*/
-
-/* Define to 1 if sig_atomic_t is already defined as volatile. */
-/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */
-
-/* Define to 1 if you have the `socket' function. */
-#define HAVE_SOCKET 1
-
-/* Define to 1 if you have the <ssl.h> header file. */
-/* #undef HAVE_SSL_H */
-
-/* Define to 1 if you have the <stdbool.h> header file. */
-#define HAVE_STDBOOL_H 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdio.h> header file. */
-#define HAVE_STDIO_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the `strcasecmp' function. */
-#define HAVE_STRCASECMP 1
-
-/* Define to 1 if you have the `strcmpi' function. */
-/* #undef HAVE_STRCMPI */
-
-/* Define to 1 if you have the `strdup' function. */
-#define HAVE_STRDUP 1
-
-/* Define to 1 if you have the `strerror_r' function. */
-#define HAVE_STRERROR_R 1
-
-/* Define to 1 if you have the `stricmp' function. */
-/* #undef HAVE_STRICMP */
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the `strlcpy' function. */
-#define HAVE_STRLCPY 1
-
-/* Define to 1 if you have the `strstr' function. */
-#define HAVE_STRSTR 1
-
-/* Define to 1 if you have the `strtok_r' function. */
-#define HAVE_STRTOK_R 1
-
-/* Define to 1 if you have the `strtoll' function. */
-#define HAVE_STRTOLL 1
-
-/* if struct sockaddr_storage is defined */
-#define HAVE_STRUCT_SOCKADDR_STORAGE 1
-
-/* Define to 1 if you have the timeval struct. */
-#define HAVE_STRUCT_TIMEVAL 1
-
-/* Define to 1 if you have the <sys/filio.h> header file. */
-#define HAVE_SYS_FILIO_H 1
-
-/* Define to 1 if you have the <sys/ioctl.h> header file. */
-#define HAVE_SYS_IOCTL_H 1
-
-/* Define to 1 if you have the <sys/param.h> header file. */
-#define HAVE_SYS_PARAM_H 1
-
-/* Define to 1 if you have the <sys/poll.h> header file. */
-/*#define HAVE_SYS_POLL_H 1*/
-
-/* Define to 1 if you have the <sys/resource.h> header file. */
-#define HAVE_SYS_RESOURCE_H 1
-
-/* Define to 1 if you have the <sys/select.h> header file. */
-#define HAVE_SYS_SELECT_H 1
-
-/* Define to 1 if you have the <sys/socket.h> header file. */
-#define HAVE_SYS_SOCKET_H 1
-
-/* Define to 1 if you have the <sys/sockio.h> header file. */
-#define HAVE_SYS_SOCKIO_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/time.h> header file. */
-#define HAVE_SYS_TIME_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <sys/utime.h> header file. */
-/* #undef HAVE_SYS_UTIME_H */
-
-/* Define to 1 if you have the <termios.h> header file. */
-/*#define HAVE_TERMIOS_H 1*/
-
-/* Define to 1 if you have the <termio.h> header file. */
-/*#define HAVE_TERMIO_H 1*/
-
-/* Define to 1 if you have the <time.h> header file. */
-#define HAVE_TIME_H 1
-
-/* Define to 1 if you have the <tld.h> header file. */
-/*#define HAVE_TLD_H 1*/
-
-/* Define to 1 if you have the `tld_strerror' function. */
-/*#define HAVE_TLD_STRERROR 1*/
-
-/* Define to 1 if you have the `uname' function. */
-#define HAVE_UNAME 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to 1 if you have the `utime' function. */
-#define HAVE_UTIME 1
-
-/* Define to 1 if you have the <utime.h> header file. */
-#define HAVE_UTIME_H 1
-
-/* Define to 1 if compiler supports C99 variadic macro style. */
-#define HAVE_VARIADIC_MACROS_C99 1
-
-/* Define to 1 if compiler supports old gcc variadic macro style. */
-/*#define HAVE_VARIADIC_MACROS_GCC 1*/
-
-/* Define to 1 if you have the winber.h header file. */
-/* #undef HAVE_WINBER_H */
-
-/* Define to 1 if you have the windows.h header file. */
-/* #undef HAVE_WINDOWS_H */
-
-/* Define to 1 if you have the winldap.h header file. */
-/* #undef HAVE_WINLDAP_H */
-
-/* Define to 1 if you have the winsock2.h header file. */
-/* #undef HAVE_WINSOCK2_H */
-
-/* Define to 1 if you have the winsock.h header file. */
-/* #undef HAVE_WINSOCK_H */
-
-/* Define this symbol if your OS supports changing the contents of argv */
-/*#define HAVE_WRITABLE_ARGV 1*/
-
-/* Define to 1 if you have the ws2tcpip.h header file. */
-/* #undef HAVE_WS2TCPIP_H */
-
-/* Define to 1 if you have the <x509.h> header file. */
-/* #undef HAVE_X509_H */
-
-/* Define to 1 if you need the lber.h header file even with ldap.h */
-/* #undef NEED_LBER_H */
-
-/* Define to 1 if you need the malloc.h header file even with stdlib.h */
-/* #undef NEED_MALLOC_H */
-
-/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
-/* #undef NEED_REENTRANT */
-
-/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */
-/* #undef NEED_THREAD_SAFE */
-
-/* cpu-machine-OS */
-#ifdef __WINS__
-#define OS "i386-pc-epoc32"
-#elif __MARM__
-#define OS "arm-unknown-epoc32"
-#else
-/* This won't happen on any current Symbian version */
-#define OS "unknown-unknown-epoc32"
-#endif
-
-/* Name of package */
-/*#define PACKAGE "curl"*/
-
-/* Define to the address where bug reports for this package should be sent. */
-/*#define PACKAGE_BUGREPORT \
- "a suitable curl mailing list => https://curl.haxx.se/mail/"*/
-
-/* Define to the full name of this package. */
-/*#define PACKAGE_NAME "curl"*/
-
-/* Define to the full name and version of this package. */
-/*#define PACKAGE_STRING "curl -"*/
-
-/* Define to the one symbol short name of this package. */
-/*#define PACKAGE_TARNAME "curl"*/
-
-/* Define to the version of this package. */
-/*#define PACKAGE_VERSION "-"*/
-
-/* a suitable file to read random data from */
-/*#define RANDOM_FILE "/dev/urandom"*/
-
-#define RECV_TYPE_ARG1 int
-#define RECV_TYPE_ARG2 void *
-#define RECV_TYPE_ARG3 size_t
-#define RECV_TYPE_ARG4 int
-#define RECV_TYPE_RETV ssize_t
-
-#define RECVFROM_TYPE_ARG1 int
-#define RECVFROM_TYPE_ARG2 void
-#define RECVFROM_TYPE_ARG3 size_t
-#define RECVFROM_TYPE_ARG4 int
-#define RECVFROM_TYPE_ARG5 struct sockaddr
-#define RECVFROM_TYPE_ARG6 size_t
-#define RECVFROM_TYPE_RETV ssize_t
-#define RECVFROM_TYPE_ARG2_IS_VOID 1
-
-#define SEND_TYPE_ARG1 int
-#define SEND_QUAL_ARG2 const
-#define SEND_TYPE_ARG2 void *
-#define SEND_TYPE_ARG3 size_t
-#define SEND_TYPE_ARG4 int
-#define SEND_TYPE_RETV ssize_t
-
-
-/* Define as the return type of signal handlers (`int' or `void'). */
-/*#define RETSIGTYPE void*/
-
-/* Define to the type of arg 1 for `select'. */
-#define SELECT_TYPE_ARG1 int
-
-/* Define to the type of args 2, 3 and 4 for `select'. */
-#define SELECT_TYPE_ARG234 (fd_set *)
-
-/* Define to the type of arg 5 for `select'. */
-#define SELECT_TYPE_ARG5 (struct timeval *)
-
-/* The size of `int', as computed by sizeof. */
-#define SIZEOF_INT 4
-
-/* The size of `off_t', as computed by sizeof. */
-#define SIZEOF_OFF_T 8
-
-/* The size of `short', as computed by sizeof. */
-#define SIZEOF_SHORT 2
-
-/* The size of `size_t', as computed by sizeof. */
-#define SIZEOF_SIZE_T 4
-
-/* The size of `time_t', as computed by sizeof. */
-#define SIZEOF_TIME_T 4
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
-#define TIME_WITH_SYS_TIME 1
-
-/* Define if you want to enable c-ares support */
-/* #undef USE_ARES */
-
-/* Define to disable non-blocking sockets */
-/* #undef USE_BLOCKING_SOCKETS */
-
-/* if GnuTLS is enabled */
-/* #undef USE_GNUTLS */
-
-/* if libSSH2 is in use */
-/*#define USE_LIBSSH2 1*/
-
-/* If you want to build curl with the built-in manual */
-/*#define USE_MANUAL 1*/
-
-/* if NSS is enabled */
-/* #undef USE_NSS */
-
-/* to enable SSPI support */
-/* #undef USE_WINDOWS_SSPI */
-
-/* Define to 1 if using yaSSL in OpenSSL compatibility mode. */
-/* #undef USE_YASSLEMUL */
-
-/* Version number of package */
-/*#define VERSION "7.18.2-CVS"*/
-
-/* Define to avoid automatic inclusion of winsock.h */
-/* #undef WIN32_LEAN_AND_MEAN */
-
-/* Define to 1 if on AIX 3.
- System headers sometimes define this.
- We just want to avoid a redefinition error message. */
-#ifndef _ALL_SOURCE
-/* # undef _ALL_SOURCE */
-#endif
-
-/* Number of bits in a file offset, on hosts where this is settable. */
-#define _FILE_OFFSET_BITS 64
-
-/* Define for large files, on AIX-style hosts. */
-/* #undef _LARGE_FILES */
-
-/* Define to empty if `const' does not conform to ANSI C. */
-/* #undef const */
-
-/* type to use in place of in_addr_t if not defined */
-/* #undef in_addr_t */
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
- calls it, or to nothing if 'inline' is not supported under any name. */
-#ifndef __cplusplus
-/* #undef inline */
-#endif
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-/* #undef size_t */
-
-/* the signed version of size_t */
-/* #undef ssize_t */
-
-/* Enabling curl debug mode when building in Symbian debug mode would work */
-/* except that debug mode introduces new exports that must be frozen. */
-#ifdef _DEBUG
-/* #define CURLDEBUG */
-#endif
-
-/* sys/cdefs.h fails to define this for WINSCW prior to Symbian OS ver. 9.4 */
-#ifndef __LONG_LONG_SUPPORTED
-#define __LONG_LONG_SUPPORTED
-#endif
-
-/* Enable appropriate header only when zlib support is enabled */
-#ifdef HAVE_LIBZ
-#define HAVE_ZLIB_H 1
-#endif
-
-#endif /* HEADER_CURL_CONFIG_SYMBIAN_H */
diff --git a/lib/config-tpf.h b/lib/config-tpf.h
index 199dfbcd5..bf69179fd 100644
--- a/lib/config-tpf.h
+++ b/lib/config-tpf.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -561,7 +561,7 @@
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT \
- "a suitable curl mailing list => https://curl.haxx.se/mail/"
+ "a suitable curl mailing list => https://curl.se/mail/"
/* Define to the full name of this package. */
#define PACKAGE_NAME "curl"
diff --git a/lib/config-vxworks.h b/lib/config-vxworks.h
index 14bf0be46..73edd530b 100644
--- a/lib/config-vxworks.h
+++ b/lib/config-vxworks.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/config-win32.h b/lib/config-win32.h
index 316043d81..e3095576f 100644
--- a/lib/config-win32.h
+++ b/lib/config-win32.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/config-win32ce.h b/lib/config-win32ce.h
index 5eb1c18f6..906083694 100644
--- a/lib/config-win32ce.h
+++ b/lib/config-win32ce.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/conncache.c b/lib/conncache.c
index 304b955f5..1b58f76b2 100644
--- a/lib/conncache.c
+++ b/lib/conncache.c
@@ -10,7 +10,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -59,7 +59,7 @@ static CURLcode bundle_create(struct connectbundle **bundlep)
(*bundlep)->num_connections = 0;
(*bundlep)->multiuse = BUNDLE_UNKNOWN;
- Curl_llist_init(&(*bundlep)->conn_list, (curl_llist_dtor) conn_llist_dtor);
+ Curl_llist_init(&(*bundlep)->conn_list, (Curl_llist_dtor) conn_llist_dtor);
return CURLE_OK;
}
@@ -87,7 +87,7 @@ static void bundle_add_conn(struct connectbundle *bundle,
static int bundle_remove_conn(struct connectbundle *bundle,
struct connectdata *conn)
{
- struct curl_llist_element *curr;
+ struct Curl_llist_element *curr;
curr = bundle->conn_list.head;
while(curr) {
@@ -206,8 +206,8 @@ static bool conncache_add_bundle(struct conncache *connc,
static void conncache_remove_bundle(struct conncache *connc,
struct connectbundle *bundle)
{
- struct curl_hash_iterator iter;
- struct curl_hash_element *he;
+ struct Curl_hash_iterator iter;
+ struct Curl_hash_element *he;
if(!connc)
return;
@@ -320,9 +320,9 @@ bool Curl_conncache_foreach(struct Curl_easy *data,
void *param,
int (*func)(struct connectdata *conn, void *param))
{
- struct curl_hash_iterator iter;
- struct curl_llist_element *curr;
- struct curl_hash_element *he;
+ struct Curl_hash_iterator iter;
+ struct Curl_llist_element *curr;
+ struct Curl_hash_element *he;
if(!connc)
return FALSE;
@@ -363,15 +363,15 @@ bool Curl_conncache_foreach(struct Curl_easy *data,
static struct connectdata *
conncache_find_first_connection(struct conncache *connc)
{
- struct curl_hash_iterator iter;
- struct curl_hash_element *he;
+ struct Curl_hash_iterator iter;
+ struct Curl_hash_element *he;
struct connectbundle *bundle;
Curl_hash_start_iterate(&connc->hash, &iter);
he = Curl_hash_next_element(&iter);
while(he) {
- struct curl_llist_element *curr;
+ struct Curl_llist_element *curr;
bundle = he->ptr;
curr = bundle->conn_list.head;
@@ -429,7 +429,7 @@ struct connectdata *
Curl_conncache_extract_bundle(struct Curl_easy *data,
struct connectbundle *bundle)
{
- struct curl_llist_element *curr;
+ struct Curl_llist_element *curr;
timediff_t highscore = -1;
timediff_t score;
struct curltime now;
@@ -477,9 +477,9 @@ struct connectdata *
Curl_conncache_extract_oldest(struct Curl_easy *data)
{
struct conncache *connc = data->state.conn_cache;
- struct curl_hash_iterator iter;
- struct curl_llist_element *curr;
- struct curl_hash_element *he;
+ struct Curl_hash_iterator iter;
+ struct Curl_llist_element *curr;
+ struct Curl_hash_element *he;
timediff_t highscore =- 1;
timediff_t score;
struct curltime now;
@@ -571,9 +571,9 @@ void Curl_conncache_close_all_connections(struct conncache *connc)
/* Useful for debugging the connection cache */
void Curl_conncache_print(struct conncache *connc)
{
- struct curl_hash_iterator iter;
- struct curl_llist_element *curr;
- struct curl_hash_element *he;
+ struct Curl_hash_iterator iter;
+ struct Curl_llist_element *curr;
+ struct Curl_hash_element *he;
if(!connc)
return;
diff --git a/lib/conncache.h b/lib/conncache.h
index 3dda21cdc..ac5460ff4 100644
--- a/lib/conncache.h
+++ b/lib/conncache.h
@@ -12,7 +12,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -30,7 +30,7 @@
*/
struct conncache {
- struct curl_hash hash;
+ struct Curl_hash hash;
size_t num_conn;
long next_connection_id;
struct curltime last_cleanup;
@@ -66,7 +66,7 @@ struct conncache {
struct connectbundle {
int multiuse; /* supports multi-use */
size_t num_connections; /* Number of connections in the bundle */
- struct curl_llist conn_list; /* The connectdata members of the bundle */
+ struct Curl_llist conn_list; /* The connectdata members of the bundle */
};
/* returns 1 on error, 0 is fine */
diff --git a/lib/connect.c b/lib/connect.c
index b000b1b2c..e65d24d9e 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -83,11 +83,6 @@
#include "curl_memory.h"
#include "memdebug.h"
-#ifdef __SYMBIAN32__
-/* This isn't actually supported under Symbian OS */
-#undef SO_NOSIGPIPE
-#endif
-
static bool verifyconnect(curl_socket_t sockfd, int *error);
#if defined(__DragonFly__) || defined(HAVE_WINSOCK_H)
@@ -678,57 +673,69 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen,
/* retrieves the start/end point information of a socket of an established
connection */
-void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
+void Curl_conninfo_remote(struct connectdata *conn, curl_socket_t sockfd)
{
- if(conn->transport == TRNSPRT_TCP) {
-#if defined(HAVE_GETPEERNAME) || defined(HAVE_GETSOCKNAME)
- if(!conn->bits.reuse && !conn->bits.tcp_fastopen) {
- struct Curl_easy *data = conn->data;
- char buffer[STRERROR_LEN];
- struct Curl_sockaddr_storage ssrem;
- struct Curl_sockaddr_storage ssloc;
- curl_socklen_t plen;
- curl_socklen_t slen;
-#ifdef HAVE_GETPEERNAME
- plen = sizeof(struct Curl_sockaddr_storage);
- if(getpeername(sockfd, (struct sockaddr*) &ssrem, &plen)) {
- int error = SOCKERRNO;
- failf(data, "getpeername() failed with errno %d: %s",
- error, Curl_strerror(error, buffer, sizeof(buffer)));
- return;
- }
-#endif
-#ifdef HAVE_GETSOCKNAME
- slen = sizeof(struct Curl_sockaddr_storage);
- memset(&ssloc, 0, sizeof(ssloc));
- if(getsockname(sockfd, (struct sockaddr*) &ssloc, &slen)) {
- int error = SOCKERRNO;
- failf(data, "getsockname() failed with errno %d: %s",
- error, Curl_strerror(error, buffer, sizeof(buffer)));
- return;
- }
-#endif
#ifdef HAVE_GETPEERNAME
- if(!Curl_addr2string((struct sockaddr*)&ssrem, plen,
- conn->primary_ip, &conn->primary_port)) {
- failf(data, "ssrem inet_ntop() failed with errno %d: %s",
- errno, Curl_strerror(errno, buffer, sizeof(buffer)));
- return;
- }
- memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
+ char buffer[STRERROR_LEN];
+ struct Curl_sockaddr_storage ssrem;
+ curl_socklen_t plen;
+ plen = sizeof(struct Curl_sockaddr_storage);
+ if(getpeername(sockfd, (struct sockaddr*) &ssrem, &plen)) {
+ int error = SOCKERRNO;
+ failf(conn->data, "getpeername() failed with errno %d: %s",
+ error, Curl_strerror(error, buffer, sizeof(buffer)));
+ return;
+ }
+ if(!Curl_addr2string((struct sockaddr*)&ssrem, plen,
+ conn->primary_ip, &conn->primary_port)) {
+ failf(conn->data, "ssrem inet_ntop() failed with errno %d: %s",
+ errno, Curl_strerror(errno, buffer, sizeof(buffer)));
+ return;
+ }
+ memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
+#else
+ (void)conn;
+ (void)sockfd;
#endif
+}
+
+/* retrieves the start/end point information of a socket of an established
+ connection */
+void Curl_conninfo_local(struct connectdata *conn, curl_socket_t sockfd)
+{
#ifdef HAVE_GETSOCKNAME
- if(!Curl_addr2string((struct sockaddr*)&ssloc, slen,
- conn->local_ip, &conn->local_port)) {
- failf(data, "ssloc inet_ntop() failed with errno %d: %s",
- errno, Curl_strerror(errno, buffer, sizeof(buffer)));
- return;
- }
+ char buffer[STRERROR_LEN];
+ struct Curl_sockaddr_storage ssloc;
+ curl_socklen_t slen;
+ slen = sizeof(struct Curl_sockaddr_storage);
+ memset(&ssloc, 0, sizeof(ssloc));
+ if(getsockname(sockfd, (struct sockaddr*) &ssloc, &slen)) {
+ int error = SOCKERRNO;
+ failf(conn->data, "getsockname() failed with errno %d: %s",
+ error, Curl_strerror(error, buffer, sizeof(buffer)));
+ return;
+ }
+ if(!Curl_addr2string((struct sockaddr*)&ssloc, slen,
+ conn->local_ip, &conn->local_port)) {
+ failf(conn->data, "ssloc inet_ntop() failed with errno %d: %s",
+ errno, Curl_strerror(errno, buffer, sizeof(buffer)));
+ return;
+ }
+#else
+ (void)conn;
+ (void)sockfd;
#endif
+}
+
+/* retrieves the start/end point information of a socket of an established
+ connection */
+void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
+{
+ if(conn->transport == TRNSPRT_TCP) {
+ if(!conn->bits.reuse && !conn->bits.tcp_fastopen) {
+ Curl_conninfo_remote(conn, sockfd);
+ Curl_conninfo_local(conn, sockfd);
}
-#else /* !HAVE_GETSOCKNAME && !HAVE_GETPEERNAME */
- (void)sockfd; /* unused */
-#endif
} /* end of TCP-only section */
/* persist connection info in session handle */
@@ -746,8 +753,8 @@ static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex,
bool *done)
{
CURLcode result = CURLE_OK;
-
#ifndef CURL_DISABLE_PROXY
+ CURLproxycode pxresult = CURLPX_OK;
if(conn->bits.socksproxy) {
/* for the secondary socket (FTP), use the "connect to host"
* but ignore the "connect to port" (use the secondary port)
@@ -767,20 +774,24 @@ static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex,
switch(conn->socks_proxy.proxytype) {
case CURLPROXY_SOCKS5:
case CURLPROXY_SOCKS5_HOSTNAME:
- result = Curl_SOCKS5(conn->socks_proxy.user, conn->socks_proxy.passwd,
- host, port, sockindex, conn, done);
+ pxresult = Curl_SOCKS5(conn->socks_proxy.user, conn->socks_proxy.passwd,
+ host, port, sockindex, conn, done);
break;
case CURLPROXY_SOCKS4:
case CURLPROXY_SOCKS4A:
- result = Curl_SOCKS4(conn->socks_proxy.user, host, port, sockindex,
- conn, done);
+ pxresult = Curl_SOCKS4(conn->socks_proxy.user, host, port, sockindex,
+ conn, done);
break;
default:
failf(conn->data, "unknown proxytype option given");
result = CURLE_COULDNT_CONNECT;
} /* switch proxytype */
+ if(pxresult) {
+ result = CURLE_PROXY;
+ conn->data->info.pxcode = pxresult;
+ }
}
else
#else
@@ -1313,10 +1324,9 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
const struct Curl_dns_entry *remotehost)
{
struct Curl_easy *data = conn->data;
- struct curltime before = Curl_now();
CURLcode result = CURLE_COULDNT_CONNECT;
int i;
- timediff_t timeout_ms = Curl_timeleft(data, &before, TRUE);
+ timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
if(timeout_ms < 0) {
/* a precaution, no need to continue if time already is up */
@@ -1336,8 +1346,12 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
conn->tempfamily[0] = conn->tempaddr[0]?
conn->tempaddr[0]->ai_family:0;
+#ifdef ENABLE_IPV6
conn->tempfamily[1] = conn->tempfamily[0] == AF_INET6 ?
AF_INET : AF_INET6;
+#else
+ conn->tempfamily[1] = AF_UNSPEC;
+#endif
ainext(conn, 1, FALSE); /* assigns conn->tempaddr[1] accordingly */
DEBUGF(infof(data, "family0 == %s, family1 == %s\n",
@@ -1416,8 +1430,7 @@ curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
}
return c->sock[FIRSTSOCKET];
}
- else
- return CURL_SOCKET_BAD;
+ return CURL_SOCKET_BAD;
}
/*
diff --git a/lib/connect.h b/lib/connect.h
index 6fd9ea878..9b1faf8fb 100644
--- a/lib/connect.h
+++ b/lib/connect.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -75,6 +75,8 @@ void Curl_sndbufset(curl_socket_t sockfd);
#endif
void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd);
+void Curl_conninfo_remote(struct connectdata *conn, curl_socket_t sockfd);
+void Curl_conninfo_local(struct connectdata *conn, curl_socket_t sockfd);
void Curl_persistconninfo(struct connectdata *conn);
int Curl_closesocket(struct connectdata *conn, curl_socket_t sock);
diff --git a/lib/content_encoding.c b/lib/content_encoding.c
index 9b0d2aa09..cdfcaf9f0 100644
--- a/lib/content_encoding.c
+++ b/lib/content_encoding.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -28,10 +28,6 @@
#ifdef HAVE_ZLIB_H
#include <zlib.h>
-#ifdef __SYMBIAN32__
-/* zlib pollutes the namespace with this definition */
-#undef WIN32
-#endif
#endif
#ifdef HAVE_BROTLI
diff --git a/lib/content_encoding.h b/lib/content_encoding.h
index bdd3f1c8c..70310875a 100644
--- a/lib/content_encoding.h
+++ b/lib/content_encoding.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/cookie.c b/lib/cookie.c
index cb7d94b10..e88678c21 100644
--- a/lib/cookie.c
+++ b/lib/cookie.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -1539,7 +1539,7 @@ static int cookie_output(struct Curl_easy *data,
}
fputs("# Netscape HTTP Cookie File\n"
- "# https://curl.haxx.se/docs/http-cookies.html\n"
+ "# https://curl.se/docs/http-cookies.html\n"
"# This file was generated by libcurl! Edit at your own risk.\n\n",
out);
diff --git a/lib/cookie.h b/lib/cookie.h
index 2ac7a518e..12f808644 100644
--- a/lib/cookie.h
+++ b/lib/cookie.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_addrinfo.c b/lib/curl_addrinfo.c
index 038987fc8..9a4d6eb3c 100644
--- a/lib/curl_addrinfo.c
+++ b/lib/curl_addrinfo.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_addrinfo.h b/lib/curl_addrinfo.h
index a0cade614..73a8c1b33 100644
--- a/lib/curl_addrinfo.h
+++ b/lib/curl_addrinfo.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_base64.h b/lib/curl_base64.h
index cfb6ee75b..d48edc424 100644
--- a/lib/curl_base64.h
+++ b/lib/curl_base64.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_config.h.cmake b/lib/curl_config.h.cmake
index dd870789e..082d76b37 100644
--- a/lib/curl_config.h.cmake
+++ b/lib/curl_config.h.cmake
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -63,8 +63,8 @@
/* to disable LDAPS */
#cmakedefine CURL_DISABLE_LDAPS 1
-/* to enable MQTT */
-#undef CURL_ENABLE_MQTT
+/* to disable MQTT */
+#cmakedefine CURL_DISABLE_MQTT 1
/* to disable POP3 */
#cmakedefine CURL_DISABLE_POP3 1
@@ -395,8 +395,11 @@
/* Define to 1 if you have the <libgen.h> header file. */
#cmakedefine HAVE_LIBGEN_H 1
-/* Define to 1 if you have the `idn' library (-lidn). */
-#cmakedefine HAVE_LIBIDN 1
+/* Define to 1 if you have the `idn2' library (-lidn2). */
+#cmakedefine HAVE_LIBIDN2 1
+
+/* Define to 1 if you have the idn2.h header file. */
+#cmakedefine HAVE_IDN2_H 1
/* Define to 1 if you have the `resolv' library (-lresolv). */
#cmakedefine HAVE_LIBRESOLV 1
@@ -470,6 +473,9 @@
/* Define to 1 if you have the <netinet/tcp.h> header file. */
#cmakedefine HAVE_NETINET_TCP_H 1
+/* Define to 1 if you have the <linux/tcp.h> header file. */
+#cmakedefine HAVE_LINUX_TCP_H 1
+
/* Define to 1 if you have the <net/if.h> header file. */
#cmakedefine HAVE_NET_IF_H 1
@@ -1014,8 +1020,8 @@ ${SIZEOF_TIME_T_CODE}
/* if Unix domain sockets are enabled */
#cmakedefine USE_UNIX_SOCKETS
-/* to enable alt-svc */
-#cmakedefine USE_ALTSVC 1
+/* to disable alt-svc */
+#cmakedefine CURL_DISABLE_ALTSVC 1
/* Define to 1 if you are building a Windows target with large file support. */
#cmakedefine USE_WIN32_LARGE_FILES 1
diff --git a/lib/curl_ctype.c b/lib/curl_ctype.c
index 1a47fb5e6..d6cd08a07 100644
--- a/lib/curl_ctype.c
+++ b/lib/curl_ctype.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_ctype.h b/lib/curl_ctype.h
index 6e94bb1b4..17dfaa094 100644
--- a/lib/curl_ctype.h
+++ b/lib/curl_ctype.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_des.c b/lib/curl_des.c
index 39c0f35ee..8c5af19cd 100644
--- a/lib/curl_des.c
+++ b/lib/curl_des.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2015 - 2019, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2015 - 2020, Steve Holme, <steve_holme@hotmail.com>.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_des.h b/lib/curl_des.h
index a42eeb53f..438706a0d 100644
--- a/lib/curl_des.h
+++ b/lib/curl_des.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2015 - 2019, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2015 - 2020, Steve Holme, <steve_holme@hotmail.com>.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_endian.c b/lib/curl_endian.c
index a774d136e..2fc25bc17 100644
--- a/lib/curl_endian.c
+++ b/lib/curl_endian.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_endian.h b/lib/curl_endian.h
index 9830e58fd..341dfaf3c 100644
--- a/lib/curl_endian.h
+++ b/lib/curl_endian.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_fnmatch.c b/lib/curl_fnmatch.c
index 027680083..9ab32ecb4 100644
--- a/lib/curl_fnmatch.c
+++ b/lib/curl_fnmatch.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_fnmatch.h b/lib/curl_fnmatch.h
index 34fccae48..1c80ea779 100644
--- a/lib/curl_fnmatch.h
+++ b/lib/curl_fnmatch.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_get_line.c b/lib/curl_get_line.c
index c4194851a..438ede704 100644
--- a/lib/curl_get_line.c
+++ b/lib/curl_get_line.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -22,6 +22,9 @@
#include "curl_setup.h"
+#if !defined(CURL_DISABLE_COOKIES) || !defined(CURL_DISABLE_ALTSVC) || \
+ defined(USE_HSTS)
+
#include "curl_get_line.h"
#include "curl_memory.h"
/* The last #include file should be: */
@@ -53,3 +56,5 @@ char *Curl_get_line(char *buf, int len, FILE *input)
}
return NULL;
}
+
+#endif /* if not disabled */
diff --git a/lib/curl_get_line.h b/lib/curl_get_line.h
index 532ab080a..597aa09a9 100644
--- a/lib/curl_get_line.h
+++ b/lib/curl_get_line.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_gethostname.c b/lib/curl_gethostname.c
index 8337c72e8..2d5ff61cf 100644
--- a/lib/curl_gethostname.c
+++ b/lib/curl_gethostname.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -48,7 +48,7 @@
* For libcurl static library release builds no overriding takes place.
*/
-int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen)
+int Curl_gethostname(char * const name, GETHOSTNAME_TYPE_ARG2 namelen)
{
#ifndef HAVE_GETHOSTNAME
diff --git a/lib/curl_gethostname.h b/lib/curl_gethostname.h
index 8ae15e6c1..2161c40ac 100644
--- a/lib/curl_gethostname.h
+++ b/lib/curl_gethostname.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -26,6 +26,6 @@
#define HOSTNAME_MAX 1024
/* This returns the local machine's un-qualified hostname */
-int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen);
+int Curl_gethostname(char * const name, GETHOSTNAME_TYPE_ARG2 namelen);
#endif /* HEADER_CURL_GETHOSTNAME_H */
diff --git a/lib/curl_gssapi.c b/lib/curl_gssapi.c
index d854ab0c7..f72430b26 100644
--- a/lib/curl_gssapi.c
+++ b/lib/curl_gssapi.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2011 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2011 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_gssapi.h b/lib/curl_gssapi.h
index 88f68dbbb..466d09ed0 100644
--- a/lib/curl_gssapi.h
+++ b/lib/curl_gssapi.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2011 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2011 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_hmac.h b/lib/curl_hmac.h
index 9b70c8468..84c73121b 100644
--- a/lib/curl_hmac.h
+++ b/lib/curl_hmac.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_sec.h b/lib/curl_krb5.h
index 7bdde269b..f0a6fa69b 100644
--- a/lib/curl_sec.h
+++ b/lib/curl_krb5.h
@@ -1,5 +1,5 @@
-#ifndef HEADER_CURL_SECURITY_H
-#define HEADER_CURL_SECURITY_H
+#ifndef HEADER_CURL_KRB5_H
+#define HEADER_CURL_KRB5_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -44,8 +44,8 @@ int Curl_sec_read_msg(struct connectdata *conn, char *,
void Curl_sec_end(struct connectdata *);
CURLcode Curl_sec_login(struct connectdata *);
int Curl_sec_request_prot(struct connectdata *conn, const char *level);
-
-extern struct Curl_sec_client_mech Curl_krb5_client_mech;
+#else
+#define Curl_sec_end(x)
#endif
-#endif /* HEADER_CURL_SECURITY_H */
+#endif /* HEADER_CURL_KRB5_H */
diff --git a/lib/curl_ldap.h b/lib/curl_ldap.h
index 912e13107..124e18b13 100644
--- a/lib/curl_ldap.h
+++ b/lib/curl_ldap.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_md4.h b/lib/curl_md4.h
index c7bb20981..f9dafcb53 100644
--- a/lib/curl_md4.h
+++ b/lib/curl_md4.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_md5.h b/lib/curl_md5.h
index e06c68edf..5739c89ca 100644
--- a/lib/curl_md5.h
+++ b/lib/curl_md5.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_memory.h b/lib/curl_memory.h
index db93014c3..ad663994c 100644
--- a/lib/curl_memory.h
+++ b/lib/curl_memory.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_memrchr.c b/lib/curl_memrchr.c
index d17c100a3..e9e67dcc6 100644
--- a/lib/curl_memrchr.c
+++ b/lib/curl_memrchr.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_memrchr.h b/lib/curl_memrchr.h
index 90a8a07cc..c8394bb43 100644
--- a/lib/curl_memrchr.h
+++ b/lib/curl_memrchr.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_multibyte.c b/lib/curl_multibyte.c
index 2c8925b53..d327c8ba7 100644
--- a/lib/curl_multibyte.c
+++ b/lib/curl_multibyte.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_multibyte.h b/lib/curl_multibyte.h
index 5f8c05afc..8adaf4978 100644
--- a/lib/curl_multibyte.h
+++ b/lib/curl_multibyte.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_ntlm_core.c b/lib/curl_ntlm_core.c
index 0eefb1587..9a075ac90 100644
--- a/lib/curl_ntlm_core.c
+++ b/lib/curl_ntlm_core.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -22,7 +22,7 @@
#include "curl_setup.h"
-#if defined(USE_NTLM)
+#if defined(USE_CURL_NTLM_CORE)
/*
* NTLM details:
@@ -50,8 +50,6 @@
in NTLM type-3 messages.
*/
-#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
-
#if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
#ifdef USE_WOLFSSL
@@ -582,15 +580,11 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
unsigned char *identity;
CURLcode result = CURLE_OK;
- /* we do the length checks below separately to avoid integer overflow risk
- on extreme data lengths */
- if((userlen > SIZE_T_MAX/2) ||
- (domlen > SIZE_T_MAX/2) ||
- ((userlen + domlen) > SIZE_T_MAX/2))
+ if((userlen > CURL_MAX_INPUT_LENGTH) || (domlen > CURL_MAX_INPUT_LENGTH))
return CURLE_OUT_OF_MEMORY;
identity_len = (userlen + domlen) * 2;
- identity = malloc(identity_len);
+ identity = malloc(identity_len + 1);
if(!identity)
return CURLE_OUT_OF_MEMORY;
@@ -744,6 +738,4 @@ CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
#endif /* USE_NTRESPONSES */
-#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
-
-#endif /* USE_NTLM */
+#endif /* USE_CURL_NTLM_CORE */
diff --git a/lib/curl_ntlm_core.h b/lib/curl_ntlm_core.h
index 7895b6470..fab628c59 100644
--- a/lib/curl_ntlm_core.h
+++ b/lib/curl_ntlm_core.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -24,7 +24,7 @@
#include "curl_setup.h"
-#if defined(USE_NTLM)
+#if defined(USE_CURL_NTLM_CORE)
/* If NSS is the first available SSL backend (see order in curl_ntlm_core.c)
then it must be initialized to be used by NTLM. */
@@ -36,8 +36,6 @@
#define NTLM_NEEDS_NSS_INIT
#endif
-#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
-
#if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
#ifdef USE_WOLFSSL
# include <wolfssl/options.h>
@@ -102,8 +100,6 @@ CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
#endif /* USE_NTRESPONSES */
-#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
-
-#endif /* USE_NTLM */
+#endif /* USE_CURL_NTLM_CORE */
#endif /* HEADER_CURL_NTLM_CORE_H */
diff --git a/lib/curl_ntlm_wb.c b/lib/curl_ntlm_wb.c
index 17a92f8ca..c11757f55 100644
--- a/lib/curl_ntlm_wb.c
+++ b/lib/curl_ntlm_wb.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_ntlm_wb.h b/lib/curl_ntlm_wb.h
index 3cf841cf2..4f847d22c 100644
--- a/lib/curl_ntlm_wb.h
+++ b/lib/curl_ntlm_wb.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_path.c b/lib/curl_path.c
index 1e216ecc0..2869af8a7 100644
--- a/lib/curl_path.c
+++ b/lib/curl_path.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -168,7 +168,7 @@ CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir)
*cpp = cp + i + strspn(cp + i, WHITESPACE);
}
else {
- /* Read to end of filename - either to white space or terminator */
+ /* Read to end of filename - either to whitespace or terminator */
end = strpbrk(cp, WHITESPACE);
if(end == NULL)
end = strchr(cp, '\0');
@@ -184,7 +184,7 @@ CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir)
(*path)[pathLength] = '\0';
cp += 3;
}
- /* Copy path name up until first "white space" */
+ /* Copy path name up until first "whitespace" */
memcpy(&(*path)[pathLength], cp, (int)(end - cp));
pathLength += (int)(end - cp);
(*path)[pathLength] = '\0';
diff --git a/lib/curl_path.h b/lib/curl_path.h
index 2f0eae1ca..28fc0347d 100644
--- a/lib/curl_path.h
+++ b/lib/curl_path.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_printf.h b/lib/curl_printf.h
index 426468fb5..e0e597a1b 100644
--- a/lib/curl_printf.h
+++ b/lib/curl_printf.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_range.c b/lib/curl_range.c
index c9314eba8..c9213d7a8 100644
--- a/lib/curl_range.c
+++ b/lib/curl_range.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_range.h b/lib/curl_range.h
index 2350df992..d1f2c6d55 100644
--- a/lib/curl_range.h
+++ b/lib/curl_range.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_rtmp.c b/lib/curl_rtmp.c
index cd49e2224..46a34d494 100644
--- a/lib/curl_rtmp.c
+++ b/lib/curl_rtmp.c
@@ -5,12 +5,12 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2010, Howard Chu, <hyc@highlandsun.com>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -79,6 +79,7 @@ const struct Curl_handler Curl_handler_rtmp = {
ZERO_NULL, /* connection_check */
PORT_RTMP, /* defport */
CURLPROTO_RTMP, /* protocol */
+ CURLPROTO_RTMP, /* family */
PROTOPT_NONE /* flags*/
};
@@ -100,6 +101,7 @@ const struct Curl_handler Curl_handler_rtmpt = {
ZERO_NULL, /* connection_check */
PORT_RTMPT, /* defport */
CURLPROTO_RTMPT, /* protocol */
+ CURLPROTO_RTMPT, /* family */
PROTOPT_NONE /* flags*/
};
@@ -121,6 +123,7 @@ const struct Curl_handler Curl_handler_rtmpe = {
ZERO_NULL, /* connection_check */
PORT_RTMP, /* defport */
CURLPROTO_RTMPE, /* protocol */
+ CURLPROTO_RTMPE, /* family */
PROTOPT_NONE /* flags*/
};
@@ -142,6 +145,7 @@ const struct Curl_handler Curl_handler_rtmpte = {
ZERO_NULL, /* connection_check */
PORT_RTMPT, /* defport */
CURLPROTO_RTMPTE, /* protocol */
+ CURLPROTO_RTMPTE, /* family */
PROTOPT_NONE /* flags*/
};
@@ -163,6 +167,7 @@ const struct Curl_handler Curl_handler_rtmps = {
ZERO_NULL, /* connection_check */
PORT_RTMPS, /* defport */
CURLPROTO_RTMPS, /* protocol */
+ CURLPROTO_RTMP, /* family */
PROTOPT_NONE /* flags*/
};
@@ -184,6 +189,7 @@ const struct Curl_handler Curl_handler_rtmpts = {
ZERO_NULL, /* connection_check */
PORT_RTMPS, /* defport */
CURLPROTO_RTMPTS, /* protocol */
+ CURLPROTO_RTMPT, /* family */
PROTOPT_NONE /* flags*/
};
diff --git a/lib/curl_rtmp.h b/lib/curl_rtmp.h
index 86a01382d..f45fa71d1 100644
--- a/lib/curl_rtmp.h
+++ b/lib/curl_rtmp.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2010 - 2019, Howard Chu, <hyc@highlandsun.com>
+ * Copyright (C) 2010 - 2020, Howard Chu, <hyc@highlandsun.com>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c
index 9b467714d..2c52c2662 100644
--- a/lib/curl_sasl.c
+++ b/lib/curl_sasl.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_sasl.h b/lib/curl_sasl.h
index 9b780f5d9..22552a98c 100644
--- a/lib/curl_sasl.h
+++ b/lib/curl_sasl.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_setup.h b/lib/curl_setup.h
index 5c5c130f6..4772f98ba 100644
--- a/lib/curl_setup.h
+++ b/lib/curl_setup.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -38,8 +38,7 @@
* Define WIN32 when build target is Win32 API
*/
-#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) && \
- !defined(__SYMBIAN32__)
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
#define WIN32
#endif
@@ -88,10 +87,6 @@
# include "config-amigaos.h"
#endif
-#ifdef __SYMBIAN32__
-# include "config-symbian.h"
-#endif
-
#ifdef __OS400__
# include "config-os400.h"
#endif
@@ -243,7 +238,7 @@
* interface doesn't support IPv4, but supports IPv6, NAT64, and DNS64,
* performing this task will result in a synthesized IPv6 address.
*/
-#ifdef __APPLE__
+#if defined(__APPLE__) && !defined(USE_ARES)
#define USE_RESOLVE_ON_IPS 1
#endif
@@ -282,10 +277,16 @@
# include <exec/execbase.h>
# include <proto/exec.h>
# include <proto/dos.h>
+# include <unistd.h>
# ifdef HAVE_PROTO_BSDSOCKET_H
# include <proto/bsdsocket.h> /* ensure bsdsocket.library use */
# define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0)
# endif
+/*
+ * In clib2 arpa/inet.h warns that some prototypes may clash
+ * with bsdsocket.library. This avoids the definition of those.
+ */
+# define __NO_NET_API
#endif
#include <stdio.h>
@@ -560,14 +561,6 @@
/* ---------------------------------------------------------------- */
/*
- * When using WINSOCK, TELNET protocol requires WINSOCK2 API.
- */
-
-#if defined(USE_WINSOCK) && (USE_WINSOCK != 2)
-# define CURL_DISABLE_TELNET 1
-#endif
-
-/*
* msvc 6.0 does not have struct sockaddr_storage and
* does not define IPPROTO_ESP in winsock2.h. But both
* are available if PSDK is properly installed.
@@ -637,13 +630,12 @@ int netware_init(void);
/* Single point where USE_NTLM definition might be defined */
#if !defined(CURL_DISABLE_NTLM) && !defined(CURL_DISABLE_CRYPTO_AUTH)
-#if defined(USE_OPENSSL) || defined(USE_WINDOWS_SSPI) || \
+#if defined(USE_OPENSSL) || defined(USE_MBEDTLS) || \
defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_SECTRANSP) || \
defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \
- defined(USE_MBEDTLS) || \
(defined(USE_WOLFSSL) && defined(HAVE_WOLFSSL_DES_ECB_ENCRYPT))
-#define USE_NTLM
+#define USE_CURL_NTLM_CORE
# if defined(USE_MBEDTLS)
/* Get definition of MBEDTLS_MD4_C */
@@ -651,6 +643,10 @@ int netware_init(void);
# endif
#endif
+
+#if defined(USE_CURL_NTLM_CORE) || defined(USE_WINDOWS_SSPI)
+#define USE_NTLM
+#endif
#endif
#ifdef CURL_WANTS_CA_BUNDLE_ENV
@@ -702,7 +698,7 @@ int netware_init(void);
defined(HAVE_WINSOCK_H) || \
defined(HAVE_WINSOCK2_H) || \
defined(HAVE_WS2TCPIP_H)
-# error "Winsock and lwIP TCP/IP stack definitions shall not coexist!"
+# error "WinSock and lwIP TCP/IP stack definitions shall not coexist!"
# endif
#endif
diff --git a/lib/curl_setup_once.h b/lib/curl_setup_once.h
index e7c00deab..ef60bc7ae 100644
--- a/lib/curl_setup_once.h
+++ b/lib/curl_setup_once.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_sha256.h b/lib/curl_sha256.h
index 35d286ceb..0fceb6329 100644
--- a/lib/curl_sha256.h
+++ b/lib/curl_sha256.h
@@ -12,7 +12,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_sspi.c b/lib/curl_sspi.c
index 4b93e1ad3..0aeea9dfd 100644
--- a/lib/curl_sspi.c
+++ b/lib/curl_sspi.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_sspi.h b/lib/curl_sspi.h
index cad6fe93f..4ea84a5ae 100644
--- a/lib/curl_sspi.h
+++ b/lib/curl_sspi.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_threads.c b/lib/curl_threads.c
index 64aa19ba7..a4a4e9acf 100644
--- a/lib/curl_threads.c
+++ b/lib/curl_threads.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -41,14 +41,14 @@
#if defined(USE_THREADS_POSIX)
-struct curl_actual_call {
+struct Curl_actual_call {
unsigned int (*func)(void *);
void *arg;
};
static void *curl_thread_create_thunk(void *arg)
{
- struct curl_actual_call *ac = arg;
+ struct Curl_actual_call *ac = arg;
unsigned int (*func)(void *) = ac->func;
void *real_arg = ac->arg;
@@ -62,7 +62,7 @@ static void *curl_thread_create_thunk(void *arg)
curl_thread_t Curl_thread_create(unsigned int (*func) (void *), void *arg)
{
curl_thread_t t = malloc(sizeof(pthread_t));
- struct curl_actual_call *ac = malloc(sizeof(struct curl_actual_call));
+ struct Curl_actual_call *ac = malloc(sizeof(struct Curl_actual_call));
if(!(ac && t))
goto err;
diff --git a/lib/curl_threads.h b/lib/curl_threads.h
index 65d1a790c..e10b7a1b0 100644
--- a/lib/curl_threads.h
+++ b/lib/curl_threads.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curlx.h b/lib/curlx.h
index beff535c0..932bb939d 100644
--- a/lib/curlx.h
+++ b/lib/curlx.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/dict.c b/lib/dict.c
index 45fffce9f..4bc8b1568 100644
--- a/lib/dict.c
+++ b/lib/dict.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -57,6 +57,7 @@
#include "escape.h"
#include "progress.h"
#include "dict.h"
+#include "curl_printf.h"
#include "strcase.h"
#include "curl_memory.h"
/* The last #include file should be: */
@@ -90,7 +91,8 @@ const struct Curl_handler Curl_handler_dict = {
ZERO_NULL, /* connection_check */
PORT_DICT, /* defport */
CURLPROTO_DICT, /* protocol */
- PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */
+ CURLPROTO_DICT, /* family */
+ PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */
};
static char *unescape_word(struct Curl_easy *data, const char *inputbuff)
@@ -126,6 +128,51 @@ static char *unescape_word(struct Curl_easy *data, const char *inputbuff)
return dictp;
}
+/* sendf() sends formatted data to the server */
+static CURLcode sendf(curl_socket_t sockfd, struct connectdata *conn,
+ const char *fmt, ...)
+{
+ struct Curl_easy *data = conn->data;
+ ssize_t bytes_written;
+ size_t write_len;
+ CURLcode result = CURLE_OK;
+ char *s;
+ char *sptr;
+ va_list ap;
+ va_start(ap, fmt);
+ s = vaprintf(fmt, ap); /* returns an allocated string */
+ va_end(ap);
+ if(!s)
+ return CURLE_OUT_OF_MEMORY; /* failure */
+
+ bytes_written = 0;
+ write_len = strlen(s);
+ sptr = s;
+
+ for(;;) {
+ /* Write the buffer to the socket */
+ result = Curl_write(conn, sockfd, sptr, write_len, &bytes_written);
+
+ if(result)
+ break;
+
+ Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written);
+
+ if((size_t)bytes_written != write_len) {
+ /* if not all was written at once, we must advance the pointer, decrease
+ the size left and try again! */
+ write_len -= bytes_written;
+ sptr += bytes_written;
+ }
+ else
+ break;
+ }
+
+ free(s); /* free the output string */
+
+ return result;
+}
+
static CURLcode dict_do(struct connectdata *conn, bool *done)
{
char *word;
@@ -183,18 +230,16 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
if(!eword)
return CURLE_OUT_OF_MEMORY;
- result = Curl_sendf(sockfd, conn,
- "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
- "MATCH "
- "%s " /* database */
- "%s " /* strategy */
- "%s\r\n" /* word */
- "QUIT\r\n",
-
- database,
- strategy,
- eword
- );
+ result = sendf(sockfd, conn,
+ "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
+ "MATCH "
+ "%s " /* database */
+ "%s " /* strategy */
+ "%s\r\n" /* word */
+ "QUIT\r\n",
+ database,
+ strategy,
+ eword);
free(eword);
@@ -233,14 +278,14 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
if(!eword)
return CURLE_OUT_OF_MEMORY;
- result = Curl_sendf(sockfd, conn,
- "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
- "DEFINE "
- "%s " /* database */
- "%s\r\n" /* word */
- "QUIT\r\n",
- database,
- eword);
+ result = sendf(sockfd, conn,
+ "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
+ "DEFINE "
+ "%s " /* database */
+ "%s\r\n" /* word */
+ "QUIT\r\n",
+ database,
+ eword);
free(eword);
@@ -261,10 +306,10 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
if(ppath[i] == ':')
ppath[i] = ' ';
}
- result = Curl_sendf(sockfd, conn,
- "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
- "%s\r\n"
- "QUIT\r\n", ppath);
+ result = sendf(sockfd, conn,
+ "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
+ "%s\r\n"
+ "QUIT\r\n", ppath);
if(result) {
failf(data, "Failed sending DICT request");
return result;
diff --git a/lib/dict.h b/lib/dict.h
index 38a55ac0d..6a6c772d1 100644
--- a/lib/dict.h
+++ b/lib/dict.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/doh.c b/lib/doh.c
index 8bc3428ff..c2b76de53 100644
--- a/lib/doh.c
+++ b/lib/doh.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -57,12 +57,13 @@ static const char * const errors[]={
"Unexpected TYPE",
"Unexpected CLASS",
"No content",
- "Bad ID"
+ "Bad ID",
+ "Name too long"
};
static const char *doh_strerror(DOHcode code)
{
- if((code >= DOH_OK) && (code <= DOH_DNS_BAD_ID))
+ if((code >= DOH_OK) && (code <= DOH_DNS_NAME_TOO_LONG))
return errors[code];
return "bad error code";
}
@@ -348,6 +349,10 @@ static CURLcode dohprobe(struct Curl_easy *data,
ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_FUNCTION, data->set.ssl.fsslctx);
if(data->set.ssl.fsslctxp)
ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_DATA, data->set.ssl.fsslctxp);
+ if(data->set.str[STRING_SSL_EC_CURVES]) {
+ ERROR_CHECK_SETOPT(CURLOPT_SSL_EC_CURVES,
+ data->set.str[STRING_SSL_EC_CURVES]);
+ }
doh->set.fmultidone = Curl_doh_done;
doh->set.dohfor = data; /* identify for which transfer this is done */
diff --git a/lib/doh.h b/lib/doh.h
index bbd4c1a65..0867584ce 100644
--- a/lib/doh.h
+++ b/lib/doh.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/dotdot.c b/lib/dotdot.c
index 7e2fed910..d14e7e502 100644
--- a/lib/dotdot.c
+++ b/lib/dotdot.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/dotdot.h b/lib/dotdot.h
index f70b1db3f..ac1ea363e 100644
--- a/lib/dotdot.h
+++ b/lib/dotdot.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/dynbuf.c b/lib/dynbuf.c
index 38d370b07..ada7e0ccf 100644
--- a/lib/dynbuf.c
+++ b/lib/dynbuf.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -21,12 +21,11 @@
***************************************************************************/
#include "curl_setup.h"
-#include "strdup.h"
#include "dynbuf.h"
-
-/* The last 3 #include files should be in this order */
#include "curl_printf.h"
+#ifdef BUILDING_LIBCURL
#include "curl_memory.h"
+#endif
#include "memdebug.h"
#define MIN_FIRST_ALLOC 32
@@ -94,11 +93,15 @@ static CURLcode dyn_nappend(struct dynbuf *s,
}
if(a != s->allc) {
- s->bufr = Curl_saferealloc(s->bufr, a);
- if(!s->bufr) {
+ /* this logic is not using Curl_saferealloc() to make the tool not have to
+ include that as well when it uses this code */
+ void *p = realloc(s->bufr, a);
+ if(!p) {
+ Curl_safefree(s->bufr);
s->leng = s->allc = 0;
return CURLE_OUT_OF_MEMORY;
}
+ s->bufr = p;
s->allc = a;
}
@@ -143,6 +146,7 @@ CURLcode Curl_dyn_tail(struct dynbuf *s, size_t trail)
else {
memmove(&s->bufr[0], &s->bufr[s->leng - trail], trail);
s->leng = trail;
+ s->bufr[s->leng] = 0;
}
return CURLE_OK;
@@ -173,15 +177,22 @@ CURLcode Curl_dyn_add(struct dynbuf *s, const char *str)
}
/*
- * Append a string printf()-style
+ * Append a string vprintf()-style
*/
-CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, ...)
+CURLcode Curl_dyn_vaddf(struct dynbuf *s, const char *fmt, va_list ap)
{
+#ifdef BUILDING_LIBCURL
+ int rc;
+ DEBUGASSERT(s);
+ DEBUGASSERT(s->init == DYNINIT);
+ DEBUGASSERT(!s->leng || s->bufr);
+ rc = Curl_dyn_vprintf(s, fmt, ap);
+
+ if(!rc)
+ return CURLE_OK;
+#else
char *str;
- va_list ap;
- va_start(ap, fmt);
str = vaprintf(fmt, ap); /* this allocs a new string to append */
- va_end(ap);
if(str) {
CURLcode result = dyn_nappend(s, (unsigned char *)str, strlen(str));
@@ -190,10 +201,27 @@ CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, ...)
}
/* If we failed, we cleanup the whole buffer and return error */
Curl_dyn_free(s);
+#endif
return CURLE_OUT_OF_MEMORY;
}
/*
+ * Append a string printf()-style
+ */
+CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, ...)
+{
+ CURLcode result;
+ va_list ap;
+ DEBUGASSERT(s);
+ DEBUGASSERT(s->init == DYNINIT);
+ DEBUGASSERT(!s->leng || s->bufr);
+ va_start(ap, fmt);
+ result = Curl_dyn_vaddf(s, fmt, ap);
+ va_end(ap);
+ return result;
+}
+
+/*
* Returns a pointer to the buffer.
*/
char *Curl_dyn_ptr(const struct dynbuf *s)
diff --git a/lib/dynbuf.h b/lib/dynbuf.h
index ecc995755..484e40c64 100644
--- a/lib/dynbuf.h
+++ b/lib/dynbuf.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -22,6 +22,23 @@
*
***************************************************************************/
+#ifndef BUILDING_LIBCURL
+/* this renames the functions so that the tool code can use the same code
+ without getting symbol collisions */
+#define Curl_dyn_init(a,b) curlx_dyn_init(a,b)
+#define Curl_dyn_add(a,b) curlx_dyn_add(a,b)
+#define Curl_dyn_addn(a,b,c) curlx_dyn_addn(a,b,c)
+#define Curl_dyn_addf curlx_dyn_addf
+#define Curl_dyn_vaddf curlx_dyn_vaddf
+#define Curl_dyn_free(a) curlx_dyn_free(a)
+#define Curl_dyn_ptr(a) curlx_dyn_ptr(a)
+#define Curl_dyn_uptr(a) curlx_dyn_uptr(a)
+#define Curl_dyn_len(a) curlx_dyn_len(a)
+#define Curl_dyn_reset(a) curlx_dyn_reset(a)
+#define Curl_dyn_tail(a,b) curlx_dyn_tail(a,b)
+#define curlx_dynbuf dynbuf /* for the struct name */
+#endif
+
struct dynbuf {
char *bufr; /* point to a null-terminated allocated buffer */
size_t leng; /* number of bytes *EXCLUDING* the zero terminator */
@@ -40,12 +57,18 @@ CURLcode Curl_dyn_add(struct dynbuf *s, const char *str)
WARN_UNUSED_RESULT;
CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, ...)
WARN_UNUSED_RESULT;
+CURLcode Curl_dyn_vaddf(struct dynbuf *s, const char *fmt, va_list ap)
+ WARN_UNUSED_RESULT;
void Curl_dyn_reset(struct dynbuf *s);
CURLcode Curl_dyn_tail(struct dynbuf *s, size_t trail);
char *Curl_dyn_ptr(const struct dynbuf *s);
unsigned char *Curl_dyn_uptr(const struct dynbuf *s);
size_t Curl_dyn_len(const struct dynbuf *s);
+/* returns 0 on success, -1 on error */
+/* The implementation of this function exists in mprintf.c */
+int Curl_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list ap_save);
+
/* Dynamic buffer max sizes */
#define DYN_DOH_RESPONSE 3000
#define DYN_DOH_CNAME 256
@@ -60,4 +83,6 @@ size_t Curl_dyn_len(const struct dynbuf *s);
#define DYN_PROXY_CONNECT_HEADERS 16384
#define DYN_QLOG_NAME 1024
#define DYN_H1_TRAILER 4096
+#define DYN_PINGPPONG_CMD (64*1024)
+#define DYN_IMAP_CMD (64*1024)
#endif
diff --git a/lib/easy.c b/lib/easy.c
index bed0de259..9439e9d9d 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -78,6 +78,8 @@
#include "system_win32.h"
#include "http2.h"
#include "dynbuf.h"
+#include "altsvc.h"
+#include "hsts.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -105,7 +107,6 @@ static long init_flags;
# pragma warning(disable:4232) /* MSVC extension, dllimport identity */
#endif
-#ifndef __SYMBIAN32__
/*
* If a memory-using function (like curl_getenv) is used before
* curl_global_init() is called, we need to have these pointers set already.
@@ -118,17 +119,6 @@ curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
#if defined(WIN32) && defined(UNICODE)
curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
#endif
-#else
-/*
- * Symbian OS doesn't support initialization to code in writable static data.
- * Initialization will occur in the curl_global_init() call.
- */
-curl_malloc_callback Curl_cmalloc;
-curl_free_callback Curl_cfree;
-curl_realloc_callback Curl_crealloc;
-curl_strdup_callback Curl_cstrdup;
-curl_calloc_callback Curl_ccalloc;
-#endif
#if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__)
# pragma warning(default:4232) /* MSVC extension, dllimport identity */
@@ -883,6 +873,26 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
goto fail;
}
+#ifdef USE_ALTSVC
+ if(data->asi) {
+ outcurl->asi = Curl_altsvc_init();
+ if(!outcurl->asi)
+ goto fail;
+ if(outcurl->set.str[STRING_ALTSVC])
+ (void)Curl_altsvc_load(outcurl->asi, outcurl->set.str[STRING_ALTSVC]);
+ }
+#endif
+#ifdef USE_HSTS
+ if(data->hsts) {
+ outcurl->hsts = Curl_hsts_init();
+ if(!outcurl->hsts)
+ goto fail;
+ if(outcurl->set.str[STRING_HSTS])
+ (void)Curl_hsts_loadfile(outcurl,
+ outcurl->hsts, outcurl->set.str[STRING_HSTS]);
+ (void)Curl_hsts_loadcb(outcurl, outcurl->hsts);
+ }
+#endif
/* Clone the resolver handle, if present, for the new handle */
if(Curl_resolver_duphandle(outcurl,
&outcurl->state.resolver,
@@ -930,6 +940,8 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
Curl_dyn_free(&outcurl->state.headerb);
Curl_safefree(outcurl->change.url);
Curl_safefree(outcurl->change.referer);
+ Curl_altsvc_cleanup(&outcurl->asi);
+ Curl_hsts_cleanup(&outcurl->hsts);
Curl_freeset(outcurl);
free(outcurl);
}
@@ -958,6 +970,7 @@ void curl_easy_reset(struct Curl_easy *data)
data->progress.flags |= PGRS_HIDE;
data->state.current_speed = -1; /* init to negative == impossible */
+ data->state.retrycount = 0; /* reset the retry counter */
/* zero out authentication data: */
memset(&data->state.authhost, 0, sizeof(struct auth));
@@ -1067,9 +1080,10 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) {
Curl_expire(data, 0, EXPIRE_RUN_NOW); /* get this handle going again */
- /* force a recv/send check of this connection, as the data might've been
- read off the socket already */
- data->conn->cselect_bits = CURL_CSELECT_IN | CURL_CSELECT_OUT;
+ if(!data->state.tempcount)
+ /* if not pausing again, force a recv/send check of this connection as
+ the data might've been read off the socket already */
+ data->conn->cselect_bits = CURL_CSELECT_IN | CURL_CSELECT_OUT;
if(data->multi)
Curl_update_timer(data->multi);
}
diff --git a/lib/easygetopt.c b/lib/easygetopt.c
new file mode 100644
index 000000000..7b2213fb2
--- /dev/null
+++ b/lib/easygetopt.c
@@ -0,0 +1,96 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ | |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * ___|___/|_| ______|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "strcase.h"
+#include "easyoptions.h"
+
+#ifndef CURL_DISABLE_GETOPTIONS
+
+/* Lookups easy options at runtime */
+static struct curl_easyoption *lookup(const char *name, CURLoption id)
+{
+ DEBUGASSERT(name || id);
+ DEBUGASSERT(!Curl_easyopts_check());
+ if(name || id) {
+ struct curl_easyoption *o = &Curl_easyopts[0];
+ do {
+ if(name) {
+ if(strcasecompare(o->name, name))
+ return o;
+ }
+ else {
+ if((o->id == id) && !(o->flags & CURLOT_FLAG_ALIAS))
+ /* don't match alias options */
+ return o;
+ }
+ o++;
+ } while(o->name);
+ }
+ return NULL;
+}
+
+const struct curl_easyoption *curl_easy_option_by_name(const char *name)
+{
+ /* when name is used, the id argument is ignored */
+ return lookup(name, CURLOPT_LASTENTRY);
+}
+
+const struct curl_easyoption *curl_easy_option_by_id(CURLoption id)
+{
+ return lookup(NULL, id);
+}
+
+/* Iterates over available options */
+const struct curl_easyoption *
+curl_easy_option_next(const struct curl_easyoption *prev)
+{
+ if(prev && prev->name) {
+ prev++;
+ if(prev->name)
+ return prev;
+ }
+ else if(!prev)
+ return &Curl_easyopts[0];
+ return NULL;
+}
+
+#else
+const struct curl_easyoption *curl_easy_option_by_name(const char *name)
+{
+ (void)name;
+ return NULL;
+}
+
+const struct curl_easyoption *curl_easy_option_by_id (CURLoption id)
+{
+ (void)id;
+ return NULL;
+}
+
+const struct curl_easyoption *
+curl_easy_option_next(const struct curl_easyoption *prev)
+{
+ (void)prev;
+ return NULL;
+}
+#endif
diff --git a/lib/easyif.h b/lib/easyif.h
index eda0d62e5..336441828 100644
--- a/lib/easyif.h
+++ b/lib/easyif.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/easyoptions.c b/lib/easyoptions.c
new file mode 100644
index 000000000..f236da23a
--- /dev/null
+++ b/lib/easyoptions.c
@@ -0,0 +1,353 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ | |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * ___|___/|_| ______|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* This source code is generated by optiontable.pl - DO NOT EDIT BY HAND */
+
+#include "curl_setup.h"
+#include "easyoptions.h"
+
+/* all easy setopt options listed in alphabetical order */
+struct curl_easyoption Curl_easyopts[] = {
+ {"ABSTRACT_UNIX_SOCKET", CURLOPT_ABSTRACT_UNIX_SOCKET, CURLOT_STRING, 0},
+ {"ACCEPTTIMEOUT_MS", CURLOPT_ACCEPTTIMEOUT_MS, CURLOT_LONG, 0},
+ {"ACCEPT_ENCODING", CURLOPT_ACCEPT_ENCODING, CURLOT_STRING, 0},
+ {"ADDRESS_SCOPE", CURLOPT_ADDRESS_SCOPE, CURLOT_LONG, 0},
+ {"ALTSVC", CURLOPT_ALTSVC, CURLOT_STRING, 0},
+ {"ALTSVC_CTRL", CURLOPT_ALTSVC_CTRL, CURLOT_LONG, 0},
+ {"APPEND", CURLOPT_APPEND, CURLOT_LONG, 0},
+ {"AUTOREFERER", CURLOPT_AUTOREFERER, CURLOT_LONG, 0},
+ {"BUFFERSIZE", CURLOPT_BUFFERSIZE, CURLOT_LONG, 0},
+ {"CAINFO", CURLOPT_CAINFO, CURLOT_STRING, 0},
+ {"CAPATH", CURLOPT_CAPATH, CURLOT_STRING, 0},
+ {"CERTINFO", CURLOPT_CERTINFO, CURLOT_LONG, 0},
+ {"CHUNK_BGN_FUNCTION", CURLOPT_CHUNK_BGN_FUNCTION, CURLOT_FUNCTION, 0},
+ {"CHUNK_DATA", CURLOPT_CHUNK_DATA, CURLOT_CBPTR, 0},
+ {"CHUNK_END_FUNCTION", CURLOPT_CHUNK_END_FUNCTION, CURLOT_FUNCTION, 0},
+ {"CLOSESOCKETDATA", CURLOPT_CLOSESOCKETDATA, CURLOT_CBPTR, 0},
+ {"CLOSESOCKETFUNCTION", CURLOPT_CLOSESOCKETFUNCTION, CURLOT_FUNCTION, 0},
+ {"CONNECTTIMEOUT", CURLOPT_CONNECTTIMEOUT, CURLOT_LONG, 0},
+ {"CONNECTTIMEOUT_MS", CURLOPT_CONNECTTIMEOUT_MS, CURLOT_LONG, 0},
+ {"CONNECT_ONLY", CURLOPT_CONNECT_ONLY, CURLOT_LONG, 0},
+ {"CONNECT_TO", CURLOPT_CONNECT_TO, CURLOT_SLIST, 0},
+ {"CONV_FROM_NETWORK_FUNCTION", CURLOPT_CONV_FROM_NETWORK_FUNCTION,
+ CURLOT_FUNCTION, 0},
+ {"CONV_FROM_UTF8_FUNCTION", CURLOPT_CONV_FROM_UTF8_FUNCTION,
+ CURLOT_FUNCTION, 0},
+ {"CONV_TO_NETWORK_FUNCTION", CURLOPT_CONV_TO_NETWORK_FUNCTION,
+ CURLOT_FUNCTION, 0},
+ {"COOKIE", CURLOPT_COOKIE, CURLOT_STRING, 0},
+ {"COOKIEFILE", CURLOPT_COOKIEFILE, CURLOT_STRING, 0},
+ {"COOKIEJAR", CURLOPT_COOKIEJAR, CURLOT_STRING, 0},
+ {"COOKIELIST", CURLOPT_COOKIELIST, CURLOT_STRING, 0},
+ {"COOKIESESSION", CURLOPT_COOKIESESSION, CURLOT_LONG, 0},
+ {"COPYPOSTFIELDS", CURLOPT_COPYPOSTFIELDS, CURLOT_OBJECT, 0},
+ {"CRLF", CURLOPT_CRLF, CURLOT_LONG, 0},
+ {"CRLFILE", CURLOPT_CRLFILE, CURLOT_STRING, 0},
+ {"CURLU", CURLOPT_CURLU, CURLOT_OBJECT, 0},
+ {"CUSTOMREQUEST", CURLOPT_CUSTOMREQUEST, CURLOT_STRING, 0},
+ {"DEBUGDATA", CURLOPT_DEBUGDATA, CURLOT_CBPTR, 0},
+ {"DEBUGFUNCTION", CURLOPT_DEBUGFUNCTION, CURLOT_FUNCTION, 0},
+ {"DEFAULT_PROTOCOL", CURLOPT_DEFAULT_PROTOCOL, CURLOT_STRING, 0},
+ {"DIRLISTONLY", CURLOPT_DIRLISTONLY, CURLOT_LONG, 0},
+ {"DISALLOW_USERNAME_IN_URL", CURLOPT_DISALLOW_USERNAME_IN_URL,
+ CURLOT_LONG, 0},
+ {"DNS_CACHE_TIMEOUT", CURLOPT_DNS_CACHE_TIMEOUT, CURLOT_LONG, 0},
+ {"DNS_INTERFACE", CURLOPT_DNS_INTERFACE, CURLOT_STRING, 0},
+ {"DNS_LOCAL_IP4", CURLOPT_DNS_LOCAL_IP4, CURLOT_STRING, 0},
+ {"DNS_LOCAL_IP6", CURLOPT_DNS_LOCAL_IP6, CURLOT_STRING, 0},
+ {"DNS_SERVERS", CURLOPT_DNS_SERVERS, CURLOT_STRING, 0},
+ {"DNS_SHUFFLE_ADDRESSES", CURLOPT_DNS_SHUFFLE_ADDRESSES, CURLOT_LONG, 0},
+ {"DNS_USE_GLOBAL_CACHE", CURLOPT_DNS_USE_GLOBAL_CACHE, CURLOT_LONG, 0},
+ {"DOH_URL", CURLOPT_DOH_URL, CURLOT_STRING, 0},
+ {"EGDSOCKET", CURLOPT_EGDSOCKET, CURLOT_STRING, 0},
+ {"ENCODING", CURLOPT_ACCEPT_ENCODING, CURLOT_STRING, CURLOT_FLAG_ALIAS},
+ {"ERRORBUFFER", CURLOPT_ERRORBUFFER, CURLOT_OBJECT, 0},
+ {"EXPECT_100_TIMEOUT_MS", CURLOPT_EXPECT_100_TIMEOUT_MS, CURLOT_LONG, 0},
+ {"FAILONERROR", CURLOPT_FAILONERROR, CURLOT_LONG, 0},
+ {"FILE", CURLOPT_WRITEDATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS},
+ {"FILETIME", CURLOPT_FILETIME, CURLOT_LONG, 0},
+ {"FNMATCH_DATA", CURLOPT_FNMATCH_DATA, CURLOT_CBPTR, 0},
+ {"FNMATCH_FUNCTION", CURLOPT_FNMATCH_FUNCTION, CURLOT_FUNCTION, 0},
+ {"FOLLOWLOCATION", CURLOPT_FOLLOWLOCATION, CURLOT_LONG, 0},
+ {"FORBID_REUSE", CURLOPT_FORBID_REUSE, CURLOT_LONG, 0},
+ {"FRESH_CONNECT", CURLOPT_FRESH_CONNECT, CURLOT_LONG, 0},
+ {"FTPAPPEND", CURLOPT_APPEND, CURLOT_LONG, CURLOT_FLAG_ALIAS},
+ {"FTPLISTONLY", CURLOPT_DIRLISTONLY, CURLOT_LONG, CURLOT_FLAG_ALIAS},
+ {"FTPPORT", CURLOPT_FTPPORT, CURLOT_STRING, 0},
+ {"FTPSSLAUTH", CURLOPT_FTPSSLAUTH, CURLOT_VALUES, 0},
+ {"FTP_ACCOUNT", CURLOPT_FTP_ACCOUNT, CURLOT_STRING, 0},
+ {"FTP_ALTERNATIVE_TO_USER", CURLOPT_FTP_ALTERNATIVE_TO_USER,
+ CURLOT_STRING, 0},
+ {"FTP_CREATE_MISSING_DIRS", CURLOPT_FTP_CREATE_MISSING_DIRS,
+ CURLOT_LONG, 0},
+ {"FTP_FILEMETHOD", CURLOPT_FTP_FILEMETHOD, CURLOT_VALUES, 0},
+ {"FTP_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT, CURLOT_LONG, 0},
+ {"FTP_SKIP_PASV_IP", CURLOPT_FTP_SKIP_PASV_IP, CURLOT_LONG, 0},
+ {"FTP_SSL", CURLOPT_USE_SSL, CURLOT_VALUES, CURLOT_FLAG_ALIAS},
+ {"FTP_SSL_CCC", CURLOPT_FTP_SSL_CCC, CURLOT_LONG, 0},
+ {"FTP_USE_EPRT", CURLOPT_FTP_USE_EPRT, CURLOT_LONG, 0},
+ {"FTP_USE_EPSV", CURLOPT_FTP_USE_EPSV, CURLOT_LONG, 0},
+ {"FTP_USE_PRET", CURLOPT_FTP_USE_PRET, CURLOT_LONG, 0},
+ {"GSSAPI_DELEGATION", CURLOPT_GSSAPI_DELEGATION, CURLOT_VALUES, 0},
+ {"HAPPY_EYEBALLS_TIMEOUT_MS", CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS,
+ CURLOT_LONG, 0},
+ {"HAPROXYPROTOCOL", CURLOPT_HAPROXYPROTOCOL, CURLOT_LONG, 0},
+ {"HEADER", CURLOPT_HEADER, CURLOT_LONG, 0},
+ {"HEADERDATA", CURLOPT_HEADERDATA, CURLOT_CBPTR, 0},
+ {"HEADERFUNCTION", CURLOPT_HEADERFUNCTION, CURLOT_FUNCTION, 0},
+ {"HEADEROPT", CURLOPT_HEADEROPT, CURLOT_VALUES, 0},
+ {"HSTS", CURLOPT_HSTS, CURLOT_STRING, 0},
+ {"HSTSREADDATA", CURLOPT_HSTSREADDATA, CURLOT_CBPTR, 0},
+ {"HSTSREADFUNCTION", CURLOPT_HSTSREADFUNCTION, CURLOT_FUNCTION, 0},
+ {"HSTSWRITEDATA", CURLOPT_HSTSWRITEDATA, CURLOT_CBPTR, 0},
+ {"HSTSWRITEFUNCTION", CURLOPT_HSTSWRITEFUNCTION, CURLOT_FUNCTION, 0},
+ {"HSTS_CTRL", CURLOPT_HSTS_CTRL, CURLOT_LONG, 0},
+ {"HTTP09_ALLOWED", CURLOPT_HTTP09_ALLOWED, CURLOT_LONG, 0},
+ {"HTTP200ALIASES", CURLOPT_HTTP200ALIASES, CURLOT_SLIST, 0},
+ {"HTTPAUTH", CURLOPT_HTTPAUTH, CURLOT_VALUES, 0},
+ {"HTTPGET", CURLOPT_HTTPGET, CURLOT_LONG, 0},
+ {"HTTPHEADER", CURLOPT_HTTPHEADER, CURLOT_SLIST, 0},
+ {"HTTPPOST", CURLOPT_HTTPPOST, CURLOT_OBJECT, 0},
+ {"HTTPPROXYTUNNEL", CURLOPT_HTTPPROXYTUNNEL, CURLOT_LONG, 0},
+ {"HTTP_CONTENT_DECODING", CURLOPT_HTTP_CONTENT_DECODING, CURLOT_LONG, 0},
+ {"HTTP_TRANSFER_DECODING", CURLOPT_HTTP_TRANSFER_DECODING, CURLOT_LONG, 0},
+ {"HTTP_VERSION", CURLOPT_HTTP_VERSION, CURLOT_VALUES, 0},
+ {"IGNORE_CONTENT_LENGTH", CURLOPT_IGNORE_CONTENT_LENGTH, CURLOT_LONG, 0},
+ {"INFILE", CURLOPT_READDATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS},
+ {"INFILESIZE", CURLOPT_INFILESIZE, CURLOT_LONG, 0},
+ {"INFILESIZE_LARGE", CURLOPT_INFILESIZE_LARGE, CURLOT_OFF_T, 0},
+ {"INTERFACE", CURLOPT_INTERFACE, CURLOT_STRING, 0},
+ {"INTERLEAVEDATA", CURLOPT_INTERLEAVEDATA, CURLOT_CBPTR, 0},
+ {"INTERLEAVEFUNCTION", CURLOPT_INTERLEAVEFUNCTION, CURLOT_FUNCTION, 0},
+ {"IOCTLDATA", CURLOPT_IOCTLDATA, CURLOT_CBPTR, 0},
+ {"IOCTLFUNCTION", CURLOPT_IOCTLFUNCTION, CURLOT_FUNCTION, 0},
+ {"IPRESOLVE", CURLOPT_IPRESOLVE, CURLOT_VALUES, 0},
+ {"ISSUERCERT", CURLOPT_ISSUERCERT, CURLOT_STRING, 0},
+ {"ISSUERCERT_BLOB", CURLOPT_ISSUERCERT_BLOB, CURLOT_BLOB, 0},
+ {"KEEP_SENDING_ON_ERROR", CURLOPT_KEEP_SENDING_ON_ERROR, CURLOT_LONG, 0},
+ {"KEYPASSWD", CURLOPT_KEYPASSWD, CURLOT_STRING, 0},
+ {"KRB4LEVEL", CURLOPT_KRBLEVEL, CURLOT_STRING, CURLOT_FLAG_ALIAS},
+ {"KRBLEVEL", CURLOPT_KRBLEVEL, CURLOT_STRING, 0},
+ {"LOCALPORT", CURLOPT_LOCALPORT, CURLOT_LONG, 0},
+ {"LOCALPORTRANGE", CURLOPT_LOCALPORTRANGE, CURLOT_LONG, 0},
+ {"LOGIN_OPTIONS", CURLOPT_LOGIN_OPTIONS, CURLOT_STRING, 0},
+ {"LOW_SPEED_LIMIT", CURLOPT_LOW_SPEED_LIMIT, CURLOT_LONG, 0},
+ {"LOW_SPEED_TIME", CURLOPT_LOW_SPEED_TIME, CURLOT_LONG, 0},
+ {"MAIL_AUTH", CURLOPT_MAIL_AUTH, CURLOT_STRING, 0},
+ {"MAIL_FROM", CURLOPT_MAIL_FROM, CURLOT_STRING, 0},
+ {"MAIL_RCPT", CURLOPT_MAIL_RCPT, CURLOT_SLIST, 0},
+ {"MAIL_RCPT_ALLLOWFAILS", CURLOPT_MAIL_RCPT_ALLLOWFAILS, CURLOT_LONG, 0},
+ {"MAXAGE_CONN", CURLOPT_MAXAGE_CONN, CURLOT_LONG, 0},
+ {"MAXCONNECTS", CURLOPT_MAXCONNECTS, CURLOT_LONG, 0},
+ {"MAXFILESIZE", CURLOPT_MAXFILESIZE, CURLOT_LONG, 0},
+ {"MAXFILESIZE_LARGE", CURLOPT_MAXFILESIZE_LARGE, CURLOT_OFF_T, 0},
+ {"MAXREDIRS", CURLOPT_MAXREDIRS, CURLOT_LONG, 0},
+ {"MAX_RECV_SPEED_LARGE", CURLOPT_MAX_RECV_SPEED_LARGE, CURLOT_OFF_T, 0},
+ {"MAX_SEND_SPEED_LARGE", CURLOPT_MAX_SEND_SPEED_LARGE, CURLOT_OFF_T, 0},
+ {"MIMEPOST", CURLOPT_MIMEPOST, CURLOT_OBJECT, 0},
+ {"NETRC", CURLOPT_NETRC, CURLOT_VALUES, 0},
+ {"NETRC_FILE", CURLOPT_NETRC_FILE, CURLOT_STRING, 0},
+ {"NEW_DIRECTORY_PERMS", CURLOPT_NEW_DIRECTORY_PERMS, CURLOT_LONG, 0},
+ {"NEW_FILE_PERMS", CURLOPT_NEW_FILE_PERMS, CURLOT_LONG, 0},
+ {"NOBODY", CURLOPT_NOBODY, CURLOT_LONG, 0},
+ {"NOPROGRESS", CURLOPT_NOPROGRESS, CURLOT_LONG, 0},
+ {"NOPROXY", CURLOPT_NOPROXY, CURLOT_STRING, 0},
+ {"NOSIGNAL", CURLOPT_NOSIGNAL, CURLOT_LONG, 0},
+ {"OPENSOCKETDATA", CURLOPT_OPENSOCKETDATA, CURLOT_CBPTR, 0},
+ {"OPENSOCKETFUNCTION", CURLOPT_OPENSOCKETFUNCTION, CURLOT_FUNCTION, 0},
+ {"PASSWORD", CURLOPT_PASSWORD, CURLOT_STRING, 0},
+ {"PATH_AS_IS", CURLOPT_PATH_AS_IS, CURLOT_LONG, 0},
+ {"PINNEDPUBLICKEY", CURLOPT_PINNEDPUBLICKEY, CURLOT_STRING, 0},
+ {"PIPEWAIT", CURLOPT_PIPEWAIT, CURLOT_LONG, 0},
+ {"PORT", CURLOPT_PORT, CURLOT_LONG, 0},
+ {"POST", CURLOPT_POST, CURLOT_LONG, 0},
+ {"POST301", CURLOPT_POSTREDIR, CURLOT_VALUES, CURLOT_FLAG_ALIAS},
+ {"POSTFIELDS", CURLOPT_POSTFIELDS, CURLOT_OBJECT, 0},
+ {"POSTFIELDSIZE", CURLOPT_POSTFIELDSIZE, CURLOT_LONG, 0},
+ {"POSTFIELDSIZE_LARGE", CURLOPT_POSTFIELDSIZE_LARGE, CURLOT_OFF_T, 0},
+ {"POSTQUOTE", CURLOPT_POSTQUOTE, CURLOT_SLIST, 0},
+ {"POSTREDIR", CURLOPT_POSTREDIR, CURLOT_VALUES, 0},
+ {"PREQUOTE", CURLOPT_PREQUOTE, CURLOT_SLIST, 0},
+ {"PRE_PROXY", CURLOPT_PRE_PROXY, CURLOT_STRING, 0},
+ {"PRIVATE", CURLOPT_PRIVATE, CURLOT_OBJECT, 0},
+ {"PROGRESSDATA", CURLOPT_XFERINFODATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS},
+ {"PROGRESSFUNCTION", CURLOPT_PROGRESSFUNCTION, CURLOT_FUNCTION, 0},
+ {"PROTOCOLS", CURLOPT_PROTOCOLS, CURLOT_LONG, 0},
+ {"PROXY", CURLOPT_PROXY, CURLOT_STRING, 0},
+ {"PROXYAUTH", CURLOPT_PROXYAUTH, CURLOT_VALUES, 0},
+ {"PROXYHEADER", CURLOPT_PROXYHEADER, CURLOT_SLIST, 0},
+ {"PROXYPASSWORD", CURLOPT_PROXYPASSWORD, CURLOT_STRING, 0},
+ {"PROXYPORT", CURLOPT_PROXYPORT, CURLOT_LONG, 0},
+ {"PROXYTYPE", CURLOPT_PROXYTYPE, CURLOT_VALUES, 0},
+ {"PROXYUSERNAME", CURLOPT_PROXYUSERNAME, CURLOT_STRING, 0},
+ {"PROXYUSERPWD", CURLOPT_PROXYUSERPWD, CURLOT_STRING, 0},
+ {"PROXY_CAINFO", CURLOPT_PROXY_CAINFO, CURLOT_STRING, 0},
+ {"PROXY_CAPATH", CURLOPT_PROXY_CAPATH, CURLOT_STRING, 0},
+ {"PROXY_CRLFILE", CURLOPT_PROXY_CRLFILE, CURLOT_STRING, 0},
+ {"PROXY_ISSUERCERT", CURLOPT_PROXY_ISSUERCERT, CURLOT_STRING, 0},
+ {"PROXY_ISSUERCERT_BLOB", CURLOPT_PROXY_ISSUERCERT_BLOB, CURLOT_BLOB, 0},
+ {"PROXY_KEYPASSWD", CURLOPT_PROXY_KEYPASSWD, CURLOT_STRING, 0},
+ {"PROXY_PINNEDPUBLICKEY", CURLOPT_PROXY_PINNEDPUBLICKEY, CURLOT_STRING, 0},
+ {"PROXY_SERVICE_NAME", CURLOPT_PROXY_SERVICE_NAME, CURLOT_STRING, 0},
+ {"PROXY_SSLCERT", CURLOPT_PROXY_SSLCERT, CURLOT_STRING, 0},
+ {"PROXY_SSLCERTTYPE", CURLOPT_PROXY_SSLCERTTYPE, CURLOT_STRING, 0},
+ {"PROXY_SSLCERT_BLOB", CURLOPT_PROXY_SSLCERT_BLOB, CURLOT_BLOB, 0},
+ {"PROXY_SSLKEY", CURLOPT_PROXY_SSLKEY, CURLOT_STRING, 0},
+ {"PROXY_SSLKEYTYPE", CURLOPT_PROXY_SSLKEYTYPE, CURLOT_STRING, 0},
+ {"PROXY_SSLKEY_BLOB", CURLOPT_PROXY_SSLKEY_BLOB, CURLOT_BLOB, 0},
+ {"PROXY_SSLVERSION", CURLOPT_PROXY_SSLVERSION, CURLOT_VALUES, 0},
+ {"PROXY_SSL_CIPHER_LIST", CURLOPT_PROXY_SSL_CIPHER_LIST, CURLOT_STRING, 0},
+ {"PROXY_SSL_OPTIONS", CURLOPT_PROXY_SSL_OPTIONS, CURLOT_LONG, 0},
+ {"PROXY_SSL_VERIFYHOST", CURLOPT_PROXY_SSL_VERIFYHOST, CURLOT_LONG, 0},
+ {"PROXY_SSL_VERIFYPEER", CURLOPT_PROXY_SSL_VERIFYPEER, CURLOT_LONG, 0},
+ {"PROXY_TLS13_CIPHERS", CURLOPT_PROXY_TLS13_CIPHERS, CURLOT_STRING, 0},
+ {"PROXY_TLSAUTH_PASSWORD", CURLOPT_PROXY_TLSAUTH_PASSWORD,
+ CURLOT_STRING, 0},
+ {"PROXY_TLSAUTH_TYPE", CURLOPT_PROXY_TLSAUTH_TYPE, CURLOT_STRING, 0},
+ {"PROXY_TLSAUTH_USERNAME", CURLOPT_PROXY_TLSAUTH_USERNAME,
+ CURLOT_STRING, 0},
+ {"PROXY_TRANSFER_MODE", CURLOPT_PROXY_TRANSFER_MODE, CURLOT_LONG, 0},
+ {"PUT", CURLOPT_PUT, CURLOT_LONG, 0},
+ {"QUOTE", CURLOPT_QUOTE, CURLOT_SLIST, 0},
+ {"RANDOM_FILE", CURLOPT_RANDOM_FILE, CURLOT_STRING, 0},
+ {"RANGE", CURLOPT_RANGE, CURLOT_STRING, 0},
+ {"READDATA", CURLOPT_READDATA, CURLOT_CBPTR, 0},
+ {"READFUNCTION", CURLOPT_READFUNCTION, CURLOT_FUNCTION, 0},
+ {"REDIR_PROTOCOLS", CURLOPT_REDIR_PROTOCOLS, CURLOT_LONG, 0},
+ {"REFERER", CURLOPT_REFERER, CURLOT_STRING, 0},
+ {"REQUEST_TARGET", CURLOPT_REQUEST_TARGET, CURLOT_STRING, 0},
+ {"RESOLVE", CURLOPT_RESOLVE, CURLOT_SLIST, 0},
+ {"RESOLVER_START_DATA", CURLOPT_RESOLVER_START_DATA, CURLOT_CBPTR, 0},
+ {"RESOLVER_START_FUNCTION", CURLOPT_RESOLVER_START_FUNCTION,
+ CURLOT_FUNCTION, 0},
+ {"RESUME_FROM", CURLOPT_RESUME_FROM, CURLOT_LONG, 0},
+ {"RESUME_FROM_LARGE", CURLOPT_RESUME_FROM_LARGE, CURLOT_OFF_T, 0},
+ {"RTSPHEADER", CURLOPT_HTTPHEADER, CURLOT_SLIST, CURLOT_FLAG_ALIAS},
+ {"RTSP_CLIENT_CSEQ", CURLOPT_RTSP_CLIENT_CSEQ, CURLOT_LONG, 0},
+ {"RTSP_REQUEST", CURLOPT_RTSP_REQUEST, CURLOT_VALUES, 0},
+ {"RTSP_SERVER_CSEQ", CURLOPT_RTSP_SERVER_CSEQ, CURLOT_LONG, 0},
+ {"RTSP_SESSION_ID", CURLOPT_RTSP_SESSION_ID, CURLOT_STRING, 0},
+ {"RTSP_STREAM_URI", CURLOPT_RTSP_STREAM_URI, CURLOT_STRING, 0},
+ {"RTSP_TRANSPORT", CURLOPT_RTSP_TRANSPORT, CURLOT_STRING, 0},
+ {"SASL_AUTHZID", CURLOPT_SASL_AUTHZID, CURLOT_STRING, 0},
+ {"SASL_IR", CURLOPT_SASL_IR, CURLOT_LONG, 0},
+ {"SEEKDATA", CURLOPT_SEEKDATA, CURLOT_CBPTR, 0},
+ {"SEEKFUNCTION", CURLOPT_SEEKFUNCTION, CURLOT_FUNCTION, 0},
+ {"SERVER_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT,
+ CURLOT_LONG, CURLOT_FLAG_ALIAS},
+ {"SERVICE_NAME", CURLOPT_SERVICE_NAME, CURLOT_STRING, 0},
+ {"SHARE", CURLOPT_SHARE, CURLOT_OBJECT, 0},
+ {"SOCKOPTDATA", CURLOPT_SOCKOPTDATA, CURLOT_CBPTR, 0},
+ {"SOCKOPTFUNCTION", CURLOPT_SOCKOPTFUNCTION, CURLOT_FUNCTION, 0},
+ {"SOCKS5_AUTH", CURLOPT_SOCKS5_AUTH, CURLOT_LONG, 0},
+ {"SOCKS5_GSSAPI_NEC", CURLOPT_SOCKS5_GSSAPI_NEC, CURLOT_LONG, 0},
+ {"SOCKS5_GSSAPI_SERVICE", CURLOPT_SOCKS5_GSSAPI_SERVICE, CURLOT_STRING, 0},
+ {"SSH_AUTH_TYPES", CURLOPT_SSH_AUTH_TYPES, CURLOT_VALUES, 0},
+ {"SSH_COMPRESSION", CURLOPT_SSH_COMPRESSION, CURLOT_LONG, 0},
+ {"SSH_HOST_PUBLIC_KEY_MD5", CURLOPT_SSH_HOST_PUBLIC_KEY_MD5,
+ CURLOT_STRING, 0},
+ {"SSH_KEYDATA", CURLOPT_SSH_KEYDATA, CURLOT_CBPTR, 0},
+ {"SSH_KEYFUNCTION", CURLOPT_SSH_KEYFUNCTION, CURLOT_FUNCTION, 0},
+ {"SSH_KNOWNHOSTS", CURLOPT_SSH_KNOWNHOSTS, CURLOT_STRING, 0},
+ {"SSH_PRIVATE_KEYFILE", CURLOPT_SSH_PRIVATE_KEYFILE, CURLOT_STRING, 0},
+ {"SSH_PUBLIC_KEYFILE", CURLOPT_SSH_PUBLIC_KEYFILE, CURLOT_STRING, 0},
+ {"SSLCERT", CURLOPT_SSLCERT, CURLOT_STRING, 0},
+ {"SSLCERTPASSWD", CURLOPT_KEYPASSWD, CURLOT_STRING, CURLOT_FLAG_ALIAS},
+ {"SSLCERTTYPE", CURLOPT_SSLCERTTYPE, CURLOT_STRING, 0},
+ {"SSLCERT_BLOB", CURLOPT_SSLCERT_BLOB, CURLOT_BLOB, 0},
+ {"SSLENGINE", CURLOPT_SSLENGINE, CURLOT_STRING, 0},
+ {"SSLENGINE_DEFAULT", CURLOPT_SSLENGINE_DEFAULT, CURLOT_LONG, 0},
+ {"SSLKEY", CURLOPT_SSLKEY, CURLOT_STRING, 0},
+ {"SSLKEYPASSWD", CURLOPT_KEYPASSWD, CURLOT_STRING, CURLOT_FLAG_ALIAS},
+ {"SSLKEYTYPE", CURLOPT_SSLKEYTYPE, CURLOT_STRING, 0},
+ {"SSLKEY_BLOB", CURLOPT_SSLKEY_BLOB, CURLOT_BLOB, 0},
+ {"SSLVERSION", CURLOPT_SSLVERSION, CURLOT_VALUES, 0},
+ {"SSL_CIPHER_LIST", CURLOPT_SSL_CIPHER_LIST, CURLOT_STRING, 0},
+ {"SSL_CTX_DATA", CURLOPT_SSL_CTX_DATA, CURLOT_CBPTR, 0},
+ {"SSL_CTX_FUNCTION", CURLOPT_SSL_CTX_FUNCTION, CURLOT_FUNCTION, 0},
+ {"SSL_EC_CURVES", CURLOPT_SSL_EC_CURVES, CURLOT_STRING, 0},
+ {"SSL_ENABLE_ALPN", CURLOPT_SSL_ENABLE_ALPN, CURLOT_LONG, 0},
+ {"SSL_ENABLE_NPN", CURLOPT_SSL_ENABLE_NPN, CURLOT_LONG, 0},
+ {"SSL_FALSESTART", CURLOPT_SSL_FALSESTART, CURLOT_LONG, 0},
+ {"SSL_OPTIONS", CURLOPT_SSL_OPTIONS, CURLOT_VALUES, 0},
+ {"SSL_SESSIONID_CACHE", CURLOPT_SSL_SESSIONID_CACHE, CURLOT_LONG, 0},
+ {"SSL_VERIFYHOST", CURLOPT_SSL_VERIFYHOST, CURLOT_LONG, 0},
+ {"SSL_VERIFYPEER", CURLOPT_SSL_VERIFYPEER, CURLOT_LONG, 0},
+ {"SSL_VERIFYSTATUS", CURLOPT_SSL_VERIFYSTATUS, CURLOT_LONG, 0},
+ {"STDERR", CURLOPT_STDERR, CURLOT_OBJECT, 0},
+ {"STREAM_DEPENDS", CURLOPT_STREAM_DEPENDS, CURLOT_OBJECT, 0},
+ {"STREAM_DEPENDS_E", CURLOPT_STREAM_DEPENDS_E, CURLOT_OBJECT, 0},
+ {"STREAM_WEIGHT", CURLOPT_STREAM_WEIGHT, CURLOT_LONG, 0},
+ {"SUPPRESS_CONNECT_HEADERS", CURLOPT_SUPPRESS_CONNECT_HEADERS,
+ CURLOT_LONG, 0},
+ {"TCP_FASTOPEN", CURLOPT_TCP_FASTOPEN, CURLOT_LONG, 0},
+ {"TCP_KEEPALIVE", CURLOPT_TCP_KEEPALIVE, CURLOT_LONG, 0},
+ {"TCP_KEEPIDLE", CURLOPT_TCP_KEEPIDLE, CURLOT_LONG, 0},
+ {"TCP_KEEPINTVL", CURLOPT_TCP_KEEPINTVL, CURLOT_LONG, 0},
+ {"TCP_NODELAY", CURLOPT_TCP_NODELAY, CURLOT_LONG, 0},
+ {"TELNETOPTIONS", CURLOPT_TELNETOPTIONS, CURLOT_SLIST, 0},
+ {"TFTP_BLKSIZE", CURLOPT_TFTP_BLKSIZE, CURLOT_LONG, 0},
+ {"TFTP_NO_OPTIONS", CURLOPT_TFTP_NO_OPTIONS, CURLOT_LONG, 0},
+ {"TIMECONDITION", CURLOPT_TIMECONDITION, CURLOT_VALUES, 0},
+ {"TIMEOUT", CURLOPT_TIMEOUT, CURLOT_LONG, 0},
+ {"TIMEOUT_MS", CURLOPT_TIMEOUT_MS, CURLOT_LONG, 0},
+ {"TIMEVALUE", CURLOPT_TIMEVALUE, CURLOT_LONG, 0},
+ {"TIMEVALUE_LARGE", CURLOPT_TIMEVALUE_LARGE, CURLOT_OFF_T, 0},
+ {"TLS13_CIPHERS", CURLOPT_TLS13_CIPHERS, CURLOT_STRING, 0},
+ {"TLSAUTH_PASSWORD", CURLOPT_TLSAUTH_PASSWORD, CURLOT_STRING, 0},
+ {"TLSAUTH_TYPE", CURLOPT_TLSAUTH_TYPE, CURLOT_STRING, 0},
+ {"TLSAUTH_USERNAME", CURLOPT_TLSAUTH_USERNAME, CURLOT_STRING, 0},
+ {"TRAILERDATA", CURLOPT_TRAILERDATA, CURLOT_CBPTR, 0},
+ {"TRAILERFUNCTION", CURLOPT_TRAILERFUNCTION, CURLOT_FUNCTION, 0},
+ {"TRANSFERTEXT", CURLOPT_TRANSFERTEXT, CURLOT_LONG, 0},
+ {"TRANSFER_ENCODING", CURLOPT_TRANSFER_ENCODING, CURLOT_LONG, 0},
+ {"UNIX_SOCKET_PATH", CURLOPT_UNIX_SOCKET_PATH, CURLOT_STRING, 0},
+ {"UNRESTRICTED_AUTH", CURLOPT_UNRESTRICTED_AUTH, CURLOT_LONG, 0},
+ {"UPKEEP_INTERVAL_MS", CURLOPT_UPKEEP_INTERVAL_MS, CURLOT_LONG, 0},
+ {"UPLOAD", CURLOPT_UPLOAD, CURLOT_LONG, 0},
+ {"UPLOAD_BUFFERSIZE", CURLOPT_UPLOAD_BUFFERSIZE, CURLOT_LONG, 0},
+ {"URL", CURLOPT_URL, CURLOT_STRING, 0},
+ {"USERAGENT", CURLOPT_USERAGENT, CURLOT_STRING, 0},
+ {"USERNAME", CURLOPT_USERNAME, CURLOT_STRING, 0},
+ {"USERPWD", CURLOPT_USERPWD, CURLOT_STRING, 0},
+ {"USE_SSL", CURLOPT_USE_SSL, CURLOT_VALUES, 0},
+ {"VERBOSE", CURLOPT_VERBOSE, CURLOT_LONG, 0},
+ {"WILDCARDMATCH", CURLOPT_WILDCARDMATCH, CURLOT_LONG, 0},
+ {"WRITEDATA", CURLOPT_WRITEDATA, CURLOT_CBPTR, 0},
+ {"WRITEFUNCTION", CURLOPT_WRITEFUNCTION, CURLOT_FUNCTION, 0},
+ {"WRITEHEADER", CURLOPT_HEADERDATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS},
+ {"XFERINFODATA", CURLOPT_XFERINFODATA, CURLOT_CBPTR, 0},
+ {"XFERINFOFUNCTION", CURLOPT_XFERINFOFUNCTION, CURLOT_FUNCTION, 0},
+ {"XOAUTH2_BEARER", CURLOPT_XOAUTH2_BEARER, CURLOT_STRING, 0},
+ {NULL, CURLOPT_LASTENTRY, 0, 0} /* end of table */
+};
+
+#ifdef DEBUGBUILD
+/*
+ * Curl_easyopts_check() is a debug-only function that returns non-zero
+ * if this source file is not in sync with the options listed in curl/curl.h
+ */
+int Curl_easyopts_check(void)
+{
+ return (CURLOPT_LASTENTRY != (304 + 1));
+}
+#endif
diff --git a/lib/easyoptions.h b/lib/easyoptions.h
new file mode 100644
index 000000000..91e11908b
--- /dev/null
+++ b/lib/easyoptions.h
@@ -0,0 +1,35 @@
+#ifndef HEADER_CURL_EASYOPTIONS_H
+#define HEADER_CURL_EASYOPTIONS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* should probably go into the public header */
+
+#include <curl/curl.h>
+
+/* generated table with all easy options */
+extern struct curl_easyoption Curl_easyopts[];
+
+#ifdef DEBUGBUILD
+int Curl_easyopts_check(void);
+#endif
+#endif
diff --git a/lib/escape.c b/lib/escape.c
index eb8110f53..e8feec1bd 100644
--- a/lib/escape.c
+++ b/lib/escape.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -86,7 +86,7 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
if(inlength < 0)
return NULL;
- Curl_dyn_init(&d, CURL_MAX_INPUT_LENGTH);
+ Curl_dyn_init(&d, CURL_MAX_INPUT_LENGTH * 3);
length = (inlength?(size_t)inlength:strlen(string));
if(!length)
diff --git a/lib/escape.h b/lib/escape.h
index 586db7e67..46cb59039 100644
--- a/lib/escape.h
+++ b/lib/escape.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/file.c b/lib/file.c
index 5be1c835c..b24f49c5e 100644
--- a/lib/file.c
+++ b/lib/file.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -67,8 +67,7 @@
#include "curl_memory.h"
#include "memdebug.h"
-#if defined(WIN32) || defined(MSDOS) || defined(__EMX__) || \
- defined(__SYMBIAN32__)
+#if defined(WIN32) || defined(MSDOS) || defined(__EMX__)
#define DOS_FILESYSTEM 1
#endif
@@ -112,6 +111,7 @@ const struct Curl_handler Curl_handler_file = {
ZERO_NULL, /* connection_check */
0, /* defport */
CURLPROTO_FILE, /* protocol */
+ CURLPROTO_FILE, /* family */
PROTOPT_NONETWORK | PROTOPT_NOURLQUERY /* flags */
};
@@ -119,8 +119,8 @@ const struct Curl_handler Curl_handler_file = {
static CURLcode file_setup_connection(struct connectdata *conn)
{
/* allocate the FILE specific struct */
- conn->data->req.protop = calloc(1, sizeof(struct FILEPROTO));
- if(!conn->data->req.protop)
+ conn->data->req.p.file = calloc(1, sizeof(struct FILEPROTO));
+ if(!conn->data->req.p.file)
return CURLE_OUT_OF_MEMORY;
return CURLE_OK;
@@ -135,7 +135,7 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
{
struct Curl_easy *data = conn->data;
char *real_path;
- struct FILEPROTO *file = data->req.protop;
+ struct FILEPROTO *file = data->req.p.file;
int fd;
#ifdef DOS_FILESYSTEM
size_t i;
@@ -209,7 +209,7 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
static CURLcode file_done(struct connectdata *conn,
CURLcode status, bool premature)
{
- struct FILEPROTO *file = conn->data->req.protop;
+ struct FILEPROTO *file = conn->data->req.p.file;
(void)status; /* not used */
(void)premature; /* not used */
@@ -227,18 +227,8 @@ static CURLcode file_done(struct connectdata *conn,
static CURLcode file_disconnect(struct connectdata *conn,
bool dead_connection)
{
- struct FILEPROTO *file = conn->data->req.protop;
(void)dead_connection; /* not used */
-
- if(file) {
- Curl_safefree(file->freepath);
- file->path = NULL;
- if(file->fd != -1)
- close(file->fd);
- file->fd = -1;
- }
-
- return CURLE_OK;
+ return file_done(conn, 0, 0);
}
#ifdef DOS_FILESYSTEM
@@ -249,7 +239,7 @@ static CURLcode file_disconnect(struct connectdata *conn,
static CURLcode file_upload(struct connectdata *conn)
{
- struct FILEPROTO *file = conn->data->req.protop;
+ struct FILEPROTO *file = conn->data->req.p.file;
const char *dir = strchr(file->path, DIRSEP);
int fd;
int mode;
@@ -391,7 +381,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
if(data->set.upload)
return file_upload(conn);
- file = conn->data->req.protop;
+ file = conn->data->req.p.file;
/* get the fd from the connection phase */
fd = file->fd;
diff --git a/lib/file.h b/lib/file.h
index f6b74a7f7..338f92e46 100644
--- a/lib/file.h
+++ b/lib/file.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/fileinfo.c b/lib/fileinfo.c
index 2630c9e46..b7e9f0f5e 100644
--- a/lib/fileinfo.c
+++ b/lib/fileinfo.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2010 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/fileinfo.h b/lib/fileinfo.h
index ed3347de4..d8beb81f3 100644
--- a/lib/fileinfo.h
+++ b/lib/fileinfo.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2010 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -27,7 +27,7 @@
struct fileinfo {
struct curl_fileinfo info;
- struct curl_llist_element list;
+ struct Curl_llist_element list;
};
struct fileinfo *Curl_fileinfo_alloc(void);
diff --git a/lib/firefox-db2pem.sh b/lib/firefox-db2pem.sh
index ee820261e..629a2e8d6 100644
--- a/lib/firefox-db2pem.sh
+++ b/lib/firefox-db2pem.sh
@@ -10,7 +10,7 @@
# *
# * This software is licensed as described in the file COPYING, which
# * you should have received as part of this distribution. The terms
-# * are also available at https://curl.haxx.se/docs/copyright.html.
+# * are also available at https://curl.se/docs/copyright.html.
# *
# * You may opt to use, copy, modify, merge, publish, distribute and/or sell
# * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/formdata.c b/lib/formdata.c
index 5b3f3f014..c976867d5 100644
--- a/lib/formdata.c
+++ b/lib/formdata.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/formdata.h b/lib/formdata.h
index 3766d38f2..5a021ceb9 100644
--- a/lib/formdata.h
+++ b/lib/formdata.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/ftp.c b/lib/ftp.c
index 32f913f44..e43305bb5 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -59,7 +59,7 @@
#include "fileinfo.h"
#include "ftplistparser.h"
#include "curl_range.h"
-#include "curl_sec.h"
+#include "curl_krb5.h"
#include "strtoofft.h"
#include "strcase.h"
#include "vtls/vtls.h"
@@ -137,14 +137,10 @@ static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks);
static CURLcode ftp_doing(struct connectdata *conn,
bool *dophase_done);
static CURLcode ftp_setup_connection(struct connectdata *conn);
-
static CURLcode init_wc_data(struct connectdata *conn);
static CURLcode wc_statemach(struct connectdata *conn);
-
static void wc_data_dtor(void *ptr);
-
static CURLcode ftp_state_retr(struct connectdata *conn, curl_off_t filesize);
-
static CURLcode ftp_readresp(curl_socket_t sockfd,
struct pingpong *pp,
int *ftpcode,
@@ -152,12 +148,6 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
static CURLcode ftp_dophase_done(struct connectdata *conn,
bool connected);
-/* easy-to-use macro: */
-#define PPSENDF(x,y,z) result = Curl_pp_sendf(x,y,z); \
- if(result) \
- return result
-
-
/*
* FTP protocol handler.
*/
@@ -180,6 +170,7 @@ const struct Curl_handler Curl_handler_ftp = {
ZERO_NULL, /* connection_check */
PORT_FTP, /* defport */
CURLPROTO_FTP, /* protocol */
+ CURLPROTO_FTP, /* family */
PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD |
PROTOPT_NOURLQUERY | PROTOPT_PROXY_AS_HTTP |
PROTOPT_WILDCARD /* flags */
@@ -209,6 +200,7 @@ const struct Curl_handler Curl_handler_ftps = {
ZERO_NULL, /* connection_check */
PORT_FTPS, /* defport */
CURLPROTO_FTPS, /* protocol */
+ CURLPROTO_FTP, /* family */
PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION |
PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY | PROTOPT_WILDCARD /* flags */
};
@@ -775,25 +767,22 @@ static void _state(struct connectdata *conn,
static CURLcode ftp_state_user(struct connectdata *conn)
{
- CURLcode result;
- /* send USER */
- PPSENDF(&conn->proto.ftpc.pp, "USER %s", conn->user?conn->user:"");
-
- state(conn, FTP_USER);
- conn->data->state.ftp_trying_alternative = FALSE;
-
- return CURLE_OK;
+ CURLcode result = Curl_pp_sendf(&conn->proto.ftpc.pp, "USER %s",
+ conn->user?conn->user:"");
+ if(!result) {
+ state(conn, FTP_USER);
+ conn->data->state.ftp_trying_alternative = FALSE;
+ }
+ return result;
}
static CURLcode ftp_state_pwd(struct connectdata *conn)
{
- CURLcode result;
-
- /* send PWD to discover our entry point */
- PPSENDF(&conn->proto.ftpc.pp, "%s", "PWD");
- state(conn, FTP_PWD);
+ CURLcode result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", "PWD");
+ if(!result)
+ state(conn, FTP_PWD);
- return CURLE_OK;
+ return result;
}
/* For the FTP "protocol connect" and "doing" phases only */
@@ -881,16 +870,19 @@ static CURLcode ftp_state_cwd(struct connectdata *conn)
where we ended up after login: */
ftpc->cwdcount = 0; /* we count this as the first path, then we add one
for all upcoming ones in the ftp->dirs[] array */
- PPSENDF(&conn->proto.ftpc.pp, "CWD %s", ftpc->entrypath);
- state(conn, FTP_CWD);
+ result = Curl_pp_sendf(&ftpc->pp, "CWD %s", ftpc->entrypath);
+ if(!result)
+ state(conn, FTP_CWD);
}
else {
if(ftpc->dirdepth) {
ftpc->cwdcount = 1;
/* issue the first CWD, the rest is sent when the CWD responses are
received... */
- PPSENDF(&conn->proto.ftpc.pp, "CWD %s", ftpc->dirs[ftpc->cwdcount -1]);
- state(conn, FTP_CWD);
+ result = Curl_pp_sendf(&ftpc->pp, "CWD %s",
+ ftpc->dirs[ftpc->cwdcount -1]);
+ if(!result)
+ state(conn, FTP_CWD);
}
else {
/* No CWD necessary */
@@ -909,7 +901,6 @@ typedef enum {
static CURLcode ftp_state_use_port(struct connectdata *conn,
ftpport fcmd) /* start with this */
-
{
CURLcode result = CURLE_OK;
struct ftp_conn *ftpc = &conn->proto.ftpc;
@@ -1326,12 +1317,12 @@ static CURLcode ftp_state_use_pasv(struct connectdata *conn)
modeoff = conn->bits.ftp_use_epsv?0:1;
- PPSENDF(&ftpc->pp, "%s", mode[modeoff]);
-
- ftpc->count1 = modeoff;
- state(conn, FTP_PASV);
- infof(conn->data, "Connect data stream passively\n");
-
+ result = Curl_pp_sendf(&ftpc->pp, "%s", mode[modeoff]);
+ if(!result) {
+ ftpc->count1 = modeoff;
+ state(conn, FTP_PASV);
+ infof(conn->data, "Connect data stream passively\n");
+ }
return result;
}
@@ -1345,7 +1336,7 @@ static CURLcode ftp_state_use_pasv(struct connectdata *conn)
static CURLcode ftp_state_prepare_transfer(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
- struct FTP *ftp = conn->data->req.protop;
+ struct FTP *ftp = conn->data->req.p.ftp;
struct Curl_easy *data = conn->data;
if(ftp->transfer != FTPTRANSFER_BODY) {
@@ -1364,23 +1355,23 @@ static CURLcode ftp_state_prepare_transfer(struct connectdata *conn)
if(data->set.ftp_use_pret) {
/* The user has requested that we send a PRET command
to prepare the server for the upcoming PASV */
- if(!conn->proto.ftpc.file) {
- PPSENDF(&conn->proto.ftpc.pp, "PRET %s",
- data->set.str[STRING_CUSTOMREQUEST]?
- data->set.str[STRING_CUSTOMREQUEST]:
- (data->set.ftp_list_only?"NLST":"LIST"));
- }
- else if(data->set.upload) {
- PPSENDF(&conn->proto.ftpc.pp, "PRET STOR %s", conn->proto.ftpc.file);
- }
- else {
- PPSENDF(&conn->proto.ftpc.pp, "PRET RETR %s", conn->proto.ftpc.file);
- }
- state(conn, FTP_PRET);
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ if(!conn->proto.ftpc.file)
+ result = Curl_pp_sendf(&ftpc->pp, "PRET %s",
+ data->set.str[STRING_CUSTOMREQUEST]?
+ data->set.str[STRING_CUSTOMREQUEST]:
+ (data->set.ftp_list_only?"NLST":"LIST"));
+ else if(data->set.upload)
+ result = Curl_pp_sendf(&ftpc->pp, "PRET STOR %s",
+ conn->proto.ftpc.file);
+ else
+ result = Curl_pp_sendf(&ftpc->pp, "PRET RETR %s",
+ conn->proto.ftpc.file);
+ if(!result)
+ state(conn, FTP_PRET);
}
- else {
+ else
result = ftp_state_use_pasv(conn);
- }
}
return result;
}
@@ -1388,7 +1379,7 @@ static CURLcode ftp_state_prepare_transfer(struct connectdata *conn)
static CURLcode ftp_state_rest(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
- struct FTP *ftp = conn->data->req.protop;
+ struct FTP *ftp = conn->data->req.p.ftp;
struct ftp_conn *ftpc = &conn->proto.ftpc;
if((ftp->transfer != FTPTRANSFER_BODY) && ftpc->file) {
@@ -1396,9 +1387,9 @@ static CURLcode ftp_state_rest(struct connectdata *conn)
/* Determine if server can respond to REST command and therefore
whether it supports range */
- PPSENDF(&conn->proto.ftpc.pp, "REST %d", 0);
-
- state(conn, FTP_REST);
+ result = Curl_pp_sendf(&ftpc->pp, "REST %d", 0);
+ if(!result)
+ state(conn, FTP_REST);
}
else
result = ftp_state_prepare_transfer(conn);
@@ -1409,16 +1400,16 @@ static CURLcode ftp_state_rest(struct connectdata *conn)
static CURLcode ftp_state_size(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
- struct FTP *ftp = conn->data->req.protop;
+ struct FTP *ftp = conn->data->req.p.ftp;
struct ftp_conn *ftpc = &conn->proto.ftpc;
if((ftp->transfer == FTPTRANSFER_INFO) && ftpc->file) {
/* if a "head"-like request is being made (on a file) */
/* we know ftpc->file is a valid pointer to a file name */
- PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file);
-
- state(conn, FTP_SIZE);
+ result = Curl_pp_sendf(&ftpc->pp, "SIZE %s", ftpc->file);
+ if(!result)
+ state(conn, FTP_SIZE);
}
else
result = ftp_state_rest(conn);
@@ -1430,7 +1421,7 @@ static CURLcode ftp_state_list(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct FTP *ftp = data->req.protop;
+ struct FTP *ftp = data->req.p.ftp;
/* If this output is to be machine-parsed, the NLST command might be better
to use, since the LIST command output is not specified or standard in any
@@ -1485,10 +1476,8 @@ static CURLcode ftp_state_list(struct connectdata *conn)
result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", cmd);
free(cmd);
- if(result)
- return result;
-
- state(conn, FTP_LIST);
+ if(!result)
+ state(conn, FTP_LIST);
return result;
}
@@ -1508,7 +1497,7 @@ static CURLcode ftp_state_stor_prequote(struct connectdata *conn)
static CURLcode ftp_state_type(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
- struct FTP *ftp = conn->data->req.protop;
+ struct FTP *ftp = conn->data->req.p.ftp;
struct Curl_easy *data = conn->data;
struct ftp_conn *ftpc = &conn->proto.ftpc;
@@ -1549,9 +1538,10 @@ static CURLcode ftp_state_mdtm(struct connectdata *conn)
/* we have requested to get the modified-time of the file, this is a white
spot as the MDTM is not mentioned in RFC959 */
- PPSENDF(&ftpc->pp, "MDTM %s", ftpc->file);
+ result = Curl_pp_sendf(&ftpc->pp, "MDTM %s", ftpc->file);
- state(conn, FTP_MDTM);
+ if(!result)
+ state(conn, FTP_MDTM);
}
else
result = ftp_state_type(conn);
@@ -1565,7 +1555,7 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
bool sizechecked)
{
CURLcode result = CURLE_OK;
- struct FTP *ftp = conn->data->req.protop;
+ struct FTP *ftp = conn->data->req.p.ftp;
struct Curl_easy *data = conn->data;
struct ftp_conn *ftpc = &conn->proto.ftpc;
@@ -1587,8 +1577,9 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
if(data->state.resume_from < 0) {
/* Got no given size to start from, figure it out */
- PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file);
- state(conn, FTP_STOR_SIZE);
+ result = Curl_pp_sendf(&ftpc->pp, "SIZE %s", ftpc->file);
+ if(!result)
+ state(conn, FTP_STOR_SIZE);
return result;
}
@@ -1650,10 +1641,10 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
/* we've passed, proceed as normal */
} /* resume_from */
- PPSENDF(&ftpc->pp, data->set.ftp_append?"APPE %s":"STOR %s",
- ftpc->file);
-
- state(conn, FTP_STOR);
+ result = Curl_pp_sendf(&ftpc->pp, data->set.ftp_append?"APPE %s":"STOR %s",
+ ftpc->file);
+ if(!result)
+ state(conn, FTP_STOR);
return result;
}
@@ -1664,7 +1655,7 @@ static CURLcode ftp_state_quote(struct connectdata *conn,
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct FTP *ftp = data->req.protop;
+ struct FTP *ftp = data->req.p.ftp;
struct ftp_conn *ftpc = &conn->proto.ftpc;
bool quote = FALSE;
struct curl_slist *item;
@@ -1711,7 +1702,9 @@ static CURLcode ftp_state_quote(struct connectdata *conn,
else
ftpc->count2 = 0; /* failure means cancel operation */
- PPSENDF(&ftpc->pp, "%s", cmd);
+ result = Curl_pp_sendf(&ftpc->pp, "%s", cmd);
+ if(result)
+ return result;
state(conn, instate);
quote = TRUE;
}
@@ -1740,12 +1733,14 @@ static CURLcode ftp_state_quote(struct connectdata *conn,
the server terminates it, otherwise the client stops if the
received byte count exceeds the reported file size. Set option
CURLOPT_IGNORE_CONTENT_LENGTH to 1 to enable this behavior.*/
- PPSENDF(&ftpc->pp, "RETR %s", ftpc->file);
- state(conn, FTP_RETR);
+ result = Curl_pp_sendf(&ftpc->pp, "RETR %s", ftpc->file);
+ if(!result)
+ state(conn, FTP_RETR);
}
else {
- PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file);
- state(conn, FTP_RETR_SIZE);
+ result = Curl_pp_sendf(&ftpc->pp, "SIZE %s", ftpc->file);
+ if(!result)
+ state(conn, FTP_RETR_SIZE);
}
}
}
@@ -1782,10 +1777,12 @@ static CURLcode ftp_epsv_disable(struct connectdata *conn)
conn->bits.ftp_use_epsv = FALSE;
conn->data->state.errorbuf = FALSE; /* allow error message to get
rewritten */
- PPSENDF(&conn->proto.ftpc.pp, "%s", "PASV");
- conn->proto.ftpc.count1++;
- /* remain in/go to the FTP_PASV state */
- state(conn, FTP_PASV);
+ result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", "PASV");
+ if(!result) {
+ conn->proto.ftpc.count1++;
+ /* remain in/go to the FTP_PASV state */
+ state(conn, FTP_PASV);
+ }
return result;
}
@@ -1864,8 +1861,8 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
else if((ftpc->count1 == 1) &&
(ftpcode == 227)) {
/* positive PASV response */
- unsigned int ip[4];
- unsigned int port[2];
+ unsigned int ip[4] = {0, 0, 0, 0};
+ unsigned int port[2] = {0, 0};
/*
* Scan for a sequence of six comma-separated numbers and use them as
@@ -1943,6 +1940,17 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
#endif
{
/* normal, direct, ftp connection */
+ DEBUGASSERT(ftpc->newhost);
+
+ /* postponed address resolution in case of tcp fastopen */
+ if(conn->bits.tcp_fastopen && !conn->bits.reuse && !ftpc->newhost[0]) {
+ Curl_conninfo_remote(conn, conn->sock[FIRSTSOCKET]);
+ Curl_safefree(ftpc->newhost);
+ ftpc->newhost = strdup(control_address(conn));
+ if(!ftpc->newhost)
+ return CURLE_OUT_OF_MEMORY;
+ }
+
rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, FALSE, &addr);
if(rc == CURLRESOLV_PENDING)
/* BLOCKING */
@@ -2033,7 +2041,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct FTP *ftp = data->req.protop;
+ struct FTP *ftp = data->req.p.ftp;
struct ftp_conn *ftpc = &conn->proto.ftpc;
switch(ftpcode) {
@@ -2092,7 +2100,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
break;
case 550: /* "No such file or directory" */
failf(data, "Given file does not exist");
- result = CURLE_FTP_COULDNT_RETR_FILE;
+ result = CURLE_REMOTE_FILE_NOT_FOUND;
break;
}
@@ -2166,7 +2174,7 @@ static CURLcode ftp_state_retr(struct connectdata *conn,
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct FTP *ftp = data->req.protop;
+ struct FTP *ftp = data->req.p.ftp;
struct ftp_conn *ftpc = &conn->proto.ftpc;
if(data->set.max_filesize && (filesize > data->set.max_filesize)) {
@@ -2229,15 +2237,16 @@ static CURLcode ftp_state_retr(struct connectdata *conn,
infof(data, "Instructs server to resume from offset %"
CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from);
- PPSENDF(&ftpc->pp, "REST %" CURL_FORMAT_CURL_OFF_T,
- data->state.resume_from);
-
- state(conn, FTP_RETR_REST);
+ result = Curl_pp_sendf(&ftpc->pp, "REST %" CURL_FORMAT_CURL_OFF_T,
+ data->state.resume_from);
+ if(!result)
+ state(conn, FTP_RETR_REST);
}
else {
/* no resume */
- PPSENDF(&ftpc->pp, "RETR %s", ftpc->file);
- state(conn, FTP_RETR);
+ result = Curl_pp_sendf(&ftpc->pp, "RETR %s", ftpc->file);
+ if(!result)
+ state(conn, FTP_RETR);
}
return result;
@@ -2272,6 +2281,10 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn,
(void)curlx_strtoofft(fdigit, NULL, 0, &filesize);
}
+ else if(ftpcode == 550) { /* "No such file or directory" */
+ failf(data, "The file does not exist");
+ return CURLE_REMOTE_FILE_NOT_FOUND;
+ }
if(instate == FTP_SIZE) {
#ifdef CURL_FTP_HTTPSTYLE_HEAD
@@ -2326,8 +2339,9 @@ static CURLcode ftp_state_rest_resp(struct connectdata *conn,
result = CURLE_FTP_COULDNT_USE_REST;
}
else {
- PPSENDF(&ftpc->pp, "RETR %s", ftpc->file);
- state(conn, FTP_RETR);
+ result = Curl_pp_sendf(&ftpc->pp, "RETR %s", ftpc->file);
+ if(!result)
+ state(conn, FTP_RETR);
}
break;
}
@@ -2378,7 +2392,7 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct FTP *ftp = data->req.protop;
+ struct FTP *ftp = data->req.p.ftp;
if((ftpcode == 150) || (ftpcode == 125)) {
@@ -2504,7 +2518,7 @@ static CURLcode ftp_state_loggedin(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
- if(conn->ssl[FIRSTSOCKET].use) {
+ if(conn->bits.ftp_use_control_ssl) {
/* PBSZ = PROTECTION BUFFER SIZE.
The 'draft-murray-auth-ftp-ssl' (draft 12, page 7) says:
@@ -2519,8 +2533,9 @@ static CURLcode ftp_state_loggedin(struct connectdata *conn)
parameter of '0' to indicate that no buffering is taking place
and the data connection should not be encapsulated.
*/
- PPSENDF(&conn->proto.ftpc.pp, "PBSZ %d", 0);
- state(conn, FTP_PBSZ);
+ result = Curl_pp_sendf(&conn->proto.ftpc.pp, "PBSZ %d", 0);
+ if(!result)
+ state(conn, FTP_PBSZ);
}
else {
result = ftp_state_pwd(conn);
@@ -2542,8 +2557,9 @@ static CURLcode ftp_state_user_resp(struct connectdata *conn,
if((ftpcode == 331) && (ftpc->state == FTP_USER)) {
/* 331 Password required for ...
(the server requires to send the user's password too) */
- PPSENDF(&ftpc->pp, "PASS %s", conn->passwd?conn->passwd:"");
- state(conn, FTP_PASS);
+ result = Curl_pp_sendf(&ftpc->pp, "PASS %s", conn->passwd?conn->passwd:"");
+ if(!result)
+ state(conn, FTP_PASS);
}
else if(ftpcode/100 == 2) {
/* 230 User ... logged in.
@@ -2552,8 +2568,10 @@ static CURLcode ftp_state_user_resp(struct connectdata *conn,
}
else if(ftpcode == 332) {
if(data->set.str[STRING_FTP_ACCOUNT]) {
- PPSENDF(&ftpc->pp, "ACCT %s", data->set.str[STRING_FTP_ACCOUNT]);
- state(conn, FTP_ACCT);
+ result = Curl_pp_sendf(&ftpc->pp, "ACCT %s",
+ data->set.str[STRING_FTP_ACCOUNT]);
+ if(!result)
+ state(conn, FTP_ACCT);
}
else {
failf(data, "ACCT requested but none available");
@@ -2569,11 +2587,13 @@ static CURLcode ftp_state_user_resp(struct connectdata *conn,
if(conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER] &&
!conn->data->state.ftp_trying_alternative) {
/* Ok, USER failed. Let's try the supplied command. */
- PPSENDF(&conn->proto.ftpc.pp, "%s",
- conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]);
- conn->data->state.ftp_trying_alternative = TRUE;
- state(conn, FTP_USER);
- result = CURLE_OK;
+ result =
+ Curl_pp_sendf(&ftpc->pp, "%s",
+ conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]);
+ if(!result) {
+ conn->data->state.ftp_trying_alternative = TRUE;
+ state(conn, FTP_USER);
+ }
}
else {
failf(data, "Access denied: %03d", ftpcode);
@@ -2649,14 +2669,8 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
}
#endif
- if(data->set.use_ssl &&
- (!conn->ssl[FIRSTSOCKET].use
-#ifndef CURL_DISABLE_PROXY
- || (conn->bits.proxy_ssl_connected[FIRSTSOCKET] &&
- !conn->proxy_ssl[FIRSTSOCKET].use)
-#endif
- )) {
- /* We don't have a SSL/TLS connection yet, but FTPS is
+ if(data->set.use_ssl && !conn->bits.ftp_use_control_ssl) {
+ /* We don't have a SSL/TLS control connection yet, but FTPS is
requested. Try a FTPS connection now */
ftpc->count3 = 0;
@@ -2675,15 +2689,12 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
(int)data->set.ftpsslauth);
return CURLE_UNKNOWN_OPTION; /* we don't know what to do */
}
- PPSENDF(&ftpc->pp, "AUTH %s", ftpauth[ftpc->count1]);
- state(conn, FTP_AUTH);
+ result = Curl_pp_sendf(&ftpc->pp, "AUTH %s", ftpauth[ftpc->count1]);
+ if(!result)
+ state(conn, FTP_AUTH);
}
- else {
+ else
result = ftp_state_user(conn);
- if(result)
- return result;
- }
-
break;
case FTP_AUTH:
@@ -2701,6 +2712,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
result = Curl_ssl_connect(conn, FIRSTSOCKET);
if(!result) {
conn->bits.ftp_use_data_ssl = FALSE; /* clear-text data */
+ conn->bits.ftp_use_control_ssl = TRUE; /* SSL on control */
result = ftp_state_user(conn);
}
}
@@ -2718,9 +2730,6 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
/* ignore the failure and continue */
result = ftp_state_user(conn);
}
-
- if(result)
- return result;
break;
case FTP_USER:
@@ -2733,10 +2742,11 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
break;
case FTP_PBSZ:
- PPSENDF(&ftpc->pp, "PROT %c",
- data->set.use_ssl == CURLUSESSL_CONTROL ? 'C' : 'P');
- state(conn, FTP_PROT);
-
+ result =
+ Curl_pp_sendf(&ftpc->pp, "PROT %c",
+ data->set.use_ssl == CURLUSESSL_CONTROL ? 'C' : 'P');
+ if(!result)
+ state(conn, FTP_PROT);
break;
case FTP_PROT:
@@ -2753,14 +2763,12 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
if(data->set.ftp_ccc) {
/* CCC - Clear Command Channel
*/
- PPSENDF(&ftpc->pp, "%s", "CCC");
- state(conn, FTP_CCC);
+ result = Curl_pp_sendf(&ftpc->pp, "%s", "CCC");
+ if(!result)
+ state(conn, FTP_CCC);
}
- else {
+ else
result = ftp_state_pwd(conn);
- if(result)
- return result;
- }
break;
case FTP_CCC:
@@ -2768,16 +2776,12 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
/* First shut down the SSL layer (note: this call will block) */
result = Curl_ssl_shutdown(conn, FIRSTSOCKET);
- if(result) {
+ if(result)
failf(conn->data, "Failed to clear the command channel (CCC)");
- return result;
- }
}
-
- /* Then continue as normal */
- result = ftp_state_pwd(conn);
- if(result)
- return result;
+ if(!result)
+ /* Then continue as normal */
+ result = ftp_state_pwd(conn);
break;
case FTP_PWD:
@@ -2843,7 +2847,6 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
systems. */
if(!ftpc->server_os && dir[0] != '/') {
-
result = Curl_pp_sendf(&ftpc->pp, "%s", "SYST");
if(result) {
free(dir);
@@ -2939,12 +2942,10 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
if((ftpcode >= 400) && !ftpc->count2) {
/* failure response code, and not allowed to fail */
failf(conn->data, "QUOT command failed with %03d", ftpcode);
- return CURLE_QUOTE_ERROR;
+ result = CURLE_QUOTE_ERROR;
}
- result = ftp_state_quote(conn, FALSE, ftpc->state);
- if(result)
- return result;
-
+ else
+ result = ftp_state_quote(conn, FALSE, ftpc->state);
break;
case FTP_CWD:
@@ -2954,29 +2955,28 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
ftpc->cwdcount && !ftpc->count2) {
/* try making it */
ftpc->count2++; /* counter to prevent CWD-MKD loops */
- PPSENDF(&ftpc->pp, "MKD %s", ftpc->dirs[ftpc->cwdcount - 1]);
- state(conn, FTP_MKD);
+ result = Curl_pp_sendf(&ftpc->pp, "MKD %s",
+ ftpc->dirs[ftpc->cwdcount - 1]);
+ if(!result)
+ state(conn, FTP_MKD);
}
else {
/* return failure */
failf(data, "Server denied you to change to the given directory");
ftpc->cwdfail = TRUE; /* don't remember this path as we failed
to enter it */
- return CURLE_REMOTE_ACCESS_DENIED;
+ result = CURLE_REMOTE_ACCESS_DENIED;
}
}
else {
/* success */
ftpc->count2 = 0;
- if(++ftpc->cwdcount <= ftpc->dirdepth) {
+ if(++ftpc->cwdcount <= ftpc->dirdepth)
/* send next CWD */
- PPSENDF(&ftpc->pp, "CWD %s", ftpc->dirs[ftpc->cwdcount - 1]);
- }
- else {
+ result = Curl_pp_sendf(&ftpc->pp, "CWD %s",
+ ftpc->dirs[ftpc->cwdcount - 1]);
+ else
result = ftp_state_mdtm(conn);
- if(result)
- return result;
- }
}
break;
@@ -2984,11 +2984,14 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
if((ftpcode/100 != 2) && !ftpc->count3--) {
/* failure to MKD the dir */
failf(data, "Failed to MKD dir: %03d", ftpcode);
- return CURLE_REMOTE_ACCESS_DENIED;
+ result = CURLE_REMOTE_ACCESS_DENIED;
+ }
+ else {
+ state(conn, FTP_CWD);
+ /* send CWD */
+ result = Curl_pp_sendf(&ftpc->pp, "CWD %s",
+ ftpc->dirs[ftpc->cwdcount - 1]);
}
- state(conn, FTP_CWD);
- /* send CWD */
- PPSENDF(&ftpc->pp, "CWD %s", ftpc->dirs[ftpc->cwdcount - 1]);
break;
case FTP_MDTM:
@@ -3091,7 +3094,7 @@ static CURLcode ftp_block_statemach(struct connectdata *conn)
*
*/
static CURLcode ftp_connect(struct connectdata *conn,
- bool *done) /* see description above */
+ bool *done) /* see description above */
{
CURLcode result;
struct ftp_conn *ftpc = &conn->proto.ftpc;
@@ -3112,8 +3115,10 @@ static CURLcode ftp_connect(struct connectdata *conn,
result = Curl_ssl_connect(conn, FIRSTSOCKET);
if(result)
return result;
+ conn->bits.ftp_use_control_ssl = TRUE;
}
+ Curl_pp_setup(pp); /* once per transfer */
Curl_pp_init(pp); /* init the generic pingpong data */
/* When we connect, we start in the state where we await the 220
@@ -3138,7 +3143,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
bool premature)
{
struct Curl_easy *data = conn->data;
- struct FTP *ftp = data->req.protop;
+ struct FTP *ftp = data->req.p.ftp;
struct ftp_conn *ftpc = &conn->proto.ftpc;
struct pingpong *pp = &ftpc->pp;
ssize_t nread;
@@ -3297,9 +3302,18 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
if(!ftpc->dont_check) {
/* 226 Transfer complete, 250 Requested file action okay, completed. */
- if((ftpcode != 226) && (ftpcode != 250)) {
+ switch(ftpcode) {
+ case 226:
+ case 250:
+ break;
+ case 552:
+ failf(data, "Exceeded storage allocation");
+ result = CURLE_REMOTE_DISK_FULL;
+ break;
+ default:
failf(data, "server did not report OK, got %d", ftpcode);
result = CURLE_PARTIAL_FILE;
+ break;
}
}
}
@@ -3368,17 +3382,17 @@ static
CURLcode ftp_sendquote(struct connectdata *conn, struct curl_slist *quote)
{
struct curl_slist *item;
- ssize_t nread;
- int ftpcode;
- CURLcode result;
struct ftp_conn *ftpc = &conn->proto.ftpc;
struct pingpong *pp = &ftpc->pp;
item = quote;
while(item) {
if(item->data) {
+ ssize_t nread;
char *cmd = item->data;
bool acceptfail = FALSE;
+ CURLcode result;
+ int ftpcode = 0;
/* if a command starts with an asterisk, which a legal FTP command never
can, the command will be allowed to fail without it causing any
@@ -3390,11 +3404,11 @@ CURLcode ftp_sendquote(struct connectdata *conn, struct curl_slist *quote)
acceptfail = TRUE;
}
- PPSENDF(&conn->proto.ftpc.pp, "%s", cmd);
-
- pp->response = Curl_now(); /* timeout relative now */
-
- result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+ result = Curl_pp_sendf(&ftpc->pp, "%s", cmd);
+ if(!result) {
+ pp->response = Curl_now(); /* timeout relative now */
+ result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+ }
if(result)
return result;
@@ -3442,12 +3456,14 @@ static CURLcode ftp_nb_type(struct connectdata *conn,
return ftp_state_type_resp(conn, 200, newstate);
}
- PPSENDF(&ftpc->pp, "TYPE %c", want);
- state(conn, newstate);
+ result = Curl_pp_sendf(&ftpc->pp, "TYPE %c", want);
+ if(!result) {
+ state(conn, newstate);
- /* keep track of our current transfer type */
- ftpc->transfertype = want;
- return CURLE_OK;
+ /* keep track of our current transfer type */
+ ftpc->transfertype = want;
+ }
+ return result;
}
/***************************************************************************
@@ -3492,7 +3508,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
bool complete = FALSE;
/* the ftp struct is inited in ftp_connect() */
- struct FTP *ftp = data->req.protop;
+ struct FTP *ftp = data->req.p.ftp;
/* if the second connection isn't done yet, wait for it */
if(!conn->bits.tcpconnect[SECONDARYSOCKET]) {
@@ -3657,7 +3673,7 @@ CURLcode ftp_perform(struct connectdata *conn,
if(conn->data->set.opt_no_body) {
/* requested no body means no transfer... */
- struct FTP *ftp = conn->data->req.protop;
+ struct FTP *ftp = conn->data->req.p.ftp;
ftp->transfer = FTPTRANSFER_INFO;
}
@@ -3692,7 +3708,7 @@ static void wc_data_dtor(void *ptr)
static CURLcode init_wc_data(struct connectdata *conn)
{
char *last_slash;
- struct FTP *ftp = conn->data->req.protop;
+ struct FTP *ftp = conn->data->req.p.ftp;
char *path = ftp->path;
struct WildcardData *wildcard = &(conn->data->wildcard);
CURLcode result = CURLE_OK;
@@ -3784,129 +3800,131 @@ static CURLcode init_wc_data(struct connectdata *conn)
return result;
}
-/* This is called recursively */
static CURLcode wc_statemach(struct connectdata *conn)
{
struct WildcardData * const wildcard = &(conn->data->wildcard);
CURLcode result = CURLE_OK;
- switch(wildcard->state) {
- case CURLWC_INIT:
- result = init_wc_data(conn);
- if(wildcard->state == CURLWC_CLEAN)
- /* only listing! */
- break;
- wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING;
- break;
+ for(;;) {
+ switch(wildcard->state) {
+ case CURLWC_INIT:
+ result = init_wc_data(conn);
+ if(wildcard->state == CURLWC_CLEAN)
+ /* only listing! */
+ return result;
+ wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING;
+ return result;
- case CURLWC_MATCHING: {
- /* In this state is LIST response successfully parsed, so lets restore
- previous WRITEFUNCTION callback and WRITEDATA pointer */
- struct ftp_wc *ftpwc = wildcard->protdata;
- conn->data->set.fwrite_func = ftpwc->backup.write_function;
- conn->data->set.out = ftpwc->backup.file_descriptor;
- ftpwc->backup.write_function = ZERO_NULL;
- ftpwc->backup.file_descriptor = NULL;
- wildcard->state = CURLWC_DOWNLOADING;
-
- if(Curl_ftp_parselist_geterror(ftpwc->parser)) {
- /* error found in LIST parsing */
- wildcard->state = CURLWC_CLEAN;
- return wc_statemach(conn);
- }
- if(wildcard->filelist.size == 0) {
- /* no corresponding file */
- wildcard->state = CURLWC_CLEAN;
- return CURLE_REMOTE_FILE_NOT_FOUND;
+ case CURLWC_MATCHING: {
+ /* In this state is LIST response successfully parsed, so lets restore
+ previous WRITEFUNCTION callback and WRITEDATA pointer */
+ struct ftp_wc *ftpwc = wildcard->protdata;
+ conn->data->set.fwrite_func = ftpwc->backup.write_function;
+ conn->data->set.out = ftpwc->backup.file_descriptor;
+ ftpwc->backup.write_function = ZERO_NULL;
+ ftpwc->backup.file_descriptor = NULL;
+ wildcard->state = CURLWC_DOWNLOADING;
+
+ if(Curl_ftp_parselist_geterror(ftpwc->parser)) {
+ /* error found in LIST parsing */
+ wildcard->state = CURLWC_CLEAN;
+ continue;
+ }
+ if(wildcard->filelist.size == 0) {
+ /* no corresponding file */
+ wildcard->state = CURLWC_CLEAN;
+ return CURLE_REMOTE_FILE_NOT_FOUND;
+ }
+ continue;
}
- return wc_statemach(conn);
- }
- case CURLWC_DOWNLOADING: {
- /* filelist has at least one file, lets get first one */
- struct ftp_conn *ftpc = &conn->proto.ftpc;
- struct curl_fileinfo *finfo = wildcard->filelist.head->ptr;
- struct FTP *ftp = conn->data->req.protop;
+ case CURLWC_DOWNLOADING: {
+ /* filelist has at least one file, lets get first one */
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
+ struct curl_fileinfo *finfo = wildcard->filelist.head->ptr;
+ struct FTP *ftp = conn->data->req.p.ftp;
- char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename);
- if(!tmp_path)
- return CURLE_OUT_OF_MEMORY;
+ char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename);
+ if(!tmp_path)
+ return CURLE_OUT_OF_MEMORY;
- /* switch default ftp->path and tmp_path */
- free(ftp->pathalloc);
- ftp->pathalloc = ftp->path = tmp_path;
-
- infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename);
- if(conn->data->set.chunk_bgn) {
- long userresponse;
- Curl_set_in_callback(conn->data, true);
- userresponse = conn->data->set.chunk_bgn(
- finfo, wildcard->customptr, (int)wildcard->filelist.size);
- Curl_set_in_callback(conn->data, false);
- switch(userresponse) {
- case CURL_CHUNK_BGN_FUNC_SKIP:
- infof(conn->data, "Wildcard - \"%s\" skipped by user\n",
- finfo->filename);
- wildcard->state = CURLWC_SKIP;
- return wc_statemach(conn);
- case CURL_CHUNK_BGN_FUNC_FAIL:
- return CURLE_CHUNK_FAILED;
+ /* switch default ftp->path and tmp_path */
+ free(ftp->pathalloc);
+ ftp->pathalloc = ftp->path = tmp_path;
+
+ infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename);
+ if(conn->data->set.chunk_bgn) {
+ long userresponse;
+ Curl_set_in_callback(conn->data, true);
+ userresponse = conn->data->set.chunk_bgn(
+ finfo, wildcard->customptr, (int)wildcard->filelist.size);
+ Curl_set_in_callback(conn->data, false);
+ switch(userresponse) {
+ case CURL_CHUNK_BGN_FUNC_SKIP:
+ infof(conn->data, "Wildcard - \"%s\" skipped by user\n",
+ finfo->filename);
+ wildcard->state = CURLWC_SKIP;
+ continue;
+ case CURL_CHUNK_BGN_FUNC_FAIL:
+ return CURLE_CHUNK_FAILED;
+ }
}
- }
- if(finfo->filetype != CURLFILETYPE_FILE) {
- wildcard->state = CURLWC_SKIP;
- return wc_statemach(conn);
- }
+ if(finfo->filetype != CURLFILETYPE_FILE) {
+ wildcard->state = CURLWC_SKIP;
+ continue;
+ }
- if(finfo->flags & CURLFINFOFLAG_KNOWN_SIZE)
- ftpc->known_filesize = finfo->size;
+ if(finfo->flags & CURLFINFOFLAG_KNOWN_SIZE)
+ ftpc->known_filesize = finfo->size;
- result = ftp_parse_url_path(conn);
- if(result)
- return result;
+ result = ftp_parse_url_path(conn);
+ if(result)
+ return result;
- /* we don't need the Curl_fileinfo of first file anymore */
- Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
+ /* we don't need the Curl_fileinfo of first file anymore */
+ Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
- if(wildcard->filelist.size == 0) { /* remains only one file to down. */
- wildcard->state = CURLWC_CLEAN;
- /* after that will be ftp_do called once again and no transfer
- will be done because of CURLWC_CLEAN state */
- return CURLE_OK;
+ if(wildcard->filelist.size == 0) { /* remains only one file to down. */
+ wildcard->state = CURLWC_CLEAN;
+ /* after that will be ftp_do called once again and no transfer
+ will be done because of CURLWC_CLEAN state */
+ return CURLE_OK;
+ }
+ return result;
}
- } break;
- case CURLWC_SKIP: {
- if(conn->data->set.chunk_end) {
- Curl_set_in_callback(conn->data, true);
- conn->data->set.chunk_end(conn->data->wildcard.customptr);
- Curl_set_in_callback(conn->data, false);
+ case CURLWC_SKIP: {
+ if(conn->data->set.chunk_end) {
+ Curl_set_in_callback(conn->data, true);
+ conn->data->set.chunk_end(conn->data->wildcard.customptr);
+ Curl_set_in_callback(conn->data, false);
+ }
+ Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
+ wildcard->state = (wildcard->filelist.size == 0) ?
+ CURLWC_CLEAN : CURLWC_DOWNLOADING;
+ continue;
}
- Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
- wildcard->state = (wildcard->filelist.size == 0) ?
- CURLWC_CLEAN : CURLWC_DOWNLOADING;
- return wc_statemach(conn);
- }
- case CURLWC_CLEAN: {
- struct ftp_wc *ftpwc = wildcard->protdata;
- result = CURLE_OK;
- if(ftpwc)
- result = Curl_ftp_parselist_geterror(ftpwc->parser);
+ case CURLWC_CLEAN: {
+ struct ftp_wc *ftpwc = wildcard->protdata;
+ result = CURLE_OK;
+ if(ftpwc)
+ result = Curl_ftp_parselist_geterror(ftpwc->parser);
- wildcard->state = result ? CURLWC_ERROR : CURLWC_DONE;
- } break;
+ wildcard->state = result ? CURLWC_ERROR : CURLWC_DONE;
+ return result;
+ }
- case CURLWC_DONE:
- case CURLWC_ERROR:
- case CURLWC_CLEAR:
- if(wildcard->dtor)
- wildcard->dtor(wildcard->protdata);
- break;
+ case CURLWC_DONE:
+ case CURLWC_ERROR:
+ case CURLWC_CLEAR:
+ if(wildcard->dtor)
+ wildcard->dtor(wildcard->protdata);
+ return result;
+ }
}
-
- return result;
+ /* UNREACHABLE */
}
/***********************************************************************
@@ -3947,64 +3965,6 @@ static CURLcode ftp_do(struct connectdata *conn, bool *done)
return result;
}
-
-CURLcode Curl_ftpsend(struct connectdata *conn, const char *cmd)
-{
- ssize_t bytes_written;
-#define SBUF_SIZE 1024
- char s[SBUF_SIZE];
- size_t write_len;
- char *sptr = s;
- CURLcode result = CURLE_OK;
-#ifdef HAVE_GSSAPI
- enum protection_level data_sec = conn->data_prot;
-#endif
-
- if(!cmd)
- return CURLE_BAD_FUNCTION_ARGUMENT;
-
- write_len = strlen(cmd);
- if(!write_len || write_len > (sizeof(s) -3))
- return CURLE_BAD_FUNCTION_ARGUMENT;
-
- memcpy(&s, cmd, write_len);
- strcpy(&s[write_len], "\r\n"); /* append a trailing CRLF */
- write_len += 2;
- bytes_written = 0;
-
- result = Curl_convert_to_network(conn->data, s, write_len);
- /* Curl_convert_to_network calls failf if unsuccessful */
- if(result)
- return result;
-
- for(;;) {
-#ifdef HAVE_GSSAPI
- conn->data_prot = PROT_CMD;
-#endif
- result = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len,
- &bytes_written);
-#ifdef HAVE_GSSAPI
- DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST);
- conn->data_prot = data_sec;
-#endif
-
- if(result)
- break;
-
- if(conn->data->set.verbose)
- Curl_debug(conn->data, CURLINFO_HEADER_OUT, sptr, (size_t)bytes_written);
-
- if(bytes_written != (ssize_t)write_len) {
- write_len -= bytes_written;
- sptr += bytes_written;
- }
- else
- break;
- }
-
- return result;
-}
-
/***********************************************************************
*
* ftp_quit()
@@ -4068,22 +4028,14 @@ static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection)
if(data->state.most_recent_ftp_entrypath == ftpc->entrypath) {
data->state.most_recent_ftp_entrypath = NULL;
}
- free(ftpc->entrypath);
- ftpc->entrypath = NULL;
+ Curl_safefree(ftpc->entrypath);
}
freedirs(ftpc);
- free(ftpc->prevpath);
- ftpc->prevpath = NULL;
- free(ftpc->server_os);
- ftpc->server_os = NULL;
-
+ Curl_safefree(ftpc->prevpath);
+ Curl_safefree(ftpc->server_os);
Curl_pp_disconnect(pp);
-
-#ifdef HAVE_GSSAPI
Curl_sec_end(conn);
-#endif
-
return CURLE_OK;
}
@@ -4099,7 +4051,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
{
struct Curl_easy *data = conn->data;
/* the ftp struct is already inited in ftp_connect() */
- struct FTP *ftp = data->req.protop;
+ struct FTP *ftp = data->req.p.ftp;
struct ftp_conn *ftpc = &conn->proto.ftpc;
const char *slashPos = NULL;
const char *fileName = NULL;
@@ -4244,7 +4196,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
static CURLcode ftp_dophase_done(struct connectdata *conn,
bool connected)
{
- struct FTP *ftp = conn->data->req.protop;
+ struct FTP *ftp = conn->data->req.p.ftp;
struct ftp_conn *ftpc = &conn->proto.ftpc;
if(connected) {
@@ -4341,7 +4293,7 @@ static CURLcode ftp_setup_connection(struct connectdata *conn)
char *type;
struct FTP *ftp;
- conn->data->req.protop = ftp = calloc(sizeof(struct FTP), 1);
+ conn->data->req.p.ftp = ftp = calloc(sizeof(struct FTP), 1);
if(NULL == ftp)
return CURLE_OUT_OF_MEMORY;
diff --git a/lib/ftp.h b/lib/ftp.h
index 06421c6a4..3ca1458ed 100644
--- a/lib/ftp.h
+++ b/lib/ftp.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -31,7 +31,6 @@ extern const struct Curl_handler Curl_handler_ftp;
extern const struct Curl_handler Curl_handler_ftps;
#endif
-CURLcode Curl_ftpsend(struct connectdata *, const char *cmd);
CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn,
int *ftpcode);
#endif /* CURL_DISABLE_FTP */
diff --git a/lib/ftplistparser.c b/lib/ftplistparser.c
index a143a7f2e..30fc9a5a7 100644
--- a/lib/ftplistparser.c
+++ b/lib/ftplistparser.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -274,7 +274,7 @@ static CURLcode ftp_pl_insert_finfo(struct connectdata *conn,
curl_fnmatch_callback compare;
struct WildcardData *wc = &conn->data->wildcard;
struct ftp_wc *ftpwc = wc->protdata;
- struct curl_llist *llist = &wc->filelist;
+ struct Curl_llist *llist = &wc->filelist;
struct ftp_parselist_data *parser = ftpwc->parser;
bool add = TRUE;
struct curl_fileinfo *finfo = &infop->info;
@@ -418,8 +418,8 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
finfo->b_data[parser->item_length - 1] = 0;
if(strncmp("total ", finfo->b_data, 6) == 0) {
char *endptr = finfo->b_data + 6;
- /* here we can deal with directory size, pass the leading white
- spaces and then the digits */
+ /* here we can deal with directory size, pass the leading
+ whitespace and then the digits */
while(ISSPACE(*endptr))
endptr++;
while(ISDIGIT(*endptr))
diff --git a/lib/ftplistparser.h b/lib/ftplistparser.h
index b34ae9b63..e4cd8201d 100644
--- a/lib/ftplistparser.h
+++ b/lib/ftplistparser.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/getenv.c b/lib/getenv.c
index e0e5d2f4b..57e392484 100644
--- a/lib/getenv.c
+++ b/lib/getenv.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/getinfo.c b/lib/getinfo.c
index ddbd635ec..af8eaf8f4 100644
--- a/lib/getinfo.c
+++ b/lib/getinfo.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -269,6 +269,9 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
/* Return the local port of the most recent (primary) connection */
*param_longp = data->info.conn_local_port;
break;
+ case CURLINFO_PROXY_ERROR:
+ *param_longp = (long)data->info.pxcode;
+ break;
case CURLINFO_CONDITION_UNMET:
if(data->info.httpcode == 304)
*param_longp = 1L;
diff --git a/lib/getinfo.h b/lib/getinfo.h
index 8d2af4266..f35d1b4b3 100644
--- a/lib/getinfo.h
+++ b/lib/getinfo.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/gopher.c b/lib/gopher.c
index fd10926b2..fc7f7ac62 100644
--- a/lib/gopher.c
+++ b/lib/gopher.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -71,6 +71,7 @@ const struct Curl_handler Curl_handler_gopher = {
ZERO_NULL, /* connection_check */
PORT_GOPHER, /* defport */
CURLPROTO_GOPHER, /* protocol */
+ CURLPROTO_GOPHER, /* family */
PROTOPT_NONE /* flags */
};
@@ -123,8 +124,6 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
sel_org = sel;
}
- /* We use Curl_write instead of Curl_sendf to make sure the entire buffer is
- sent, which could be sizeable with long selectors. */
k = curlx_uztosz(len);
for(;;) {
@@ -170,9 +169,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
free(sel_org);
if(!result)
- /* We can use Curl_sendf to send the terminal \r\n relatively safely and
- save allocing another string/doing another _write loop. */
- result = Curl_sendf(sockfd, conn, "\r\n");
+ result = Curl_write(conn, sockfd, "\r\n", 2, &amount);
if(result) {
failf(data, "Failed sending Gopher request");
return result;
diff --git a/lib/gopher.h b/lib/gopher.h
index dec2557fc..b35fa4509 100644
--- a/lib/gopher.h
+++ b/lib/gopher.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/hash.c b/lib/hash.c
index 9e6e3fcee..3c0796b9b 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -34,8 +34,8 @@
static void
hash_element_dtor(void *user, void *element)
{
- struct curl_hash *h = (struct curl_hash *) user;
- struct curl_hash_element *e = (struct curl_hash_element *) element;
+ struct Curl_hash *h = (struct Curl_hash *) user;
+ struct Curl_hash_element *e = (struct Curl_hash_element *) element;
if(e->ptr) {
h->dtor(e->ptr);
@@ -54,11 +54,11 @@ hash_element_dtor(void *user, void *element)
* @unittest: 1603
*/
int
-Curl_hash_init(struct curl_hash *h,
+Curl_hash_init(struct Curl_hash *h,
int slots,
hash_function hfunc,
comp_function comparator,
- curl_hash_dtor dtor)
+ Curl_hash_dtor dtor)
{
if(!slots || !hfunc || !comparator ||!dtor) {
return 1; /* failure */
@@ -70,22 +70,22 @@ Curl_hash_init(struct curl_hash *h,
h->size = 0;
h->slots = slots;
- h->table = malloc(slots * sizeof(struct curl_llist));
+ h->table = malloc(slots * sizeof(struct Curl_llist));
if(h->table) {
int i;
for(i = 0; i < slots; ++i)
- Curl_llist_init(&h->table[i], (curl_llist_dtor) hash_element_dtor);
+ Curl_llist_init(&h->table[i], (Curl_llist_dtor) hash_element_dtor);
return 0; /* fine */
}
h->slots = 0;
return 1; /* failure */
}
-static struct curl_hash_element *
+static struct Curl_hash_element *
mk_hash_element(const void *key, size_t key_len, const void *p)
{
/* allocate the struct plus memory after it to store the key */
- struct curl_hash_element *he = malloc(sizeof(struct curl_hash_element) +
+ struct Curl_hash_element *he = malloc(sizeof(struct Curl_hash_element) +
key_len);
if(he) {
/* copy the key */
@@ -106,14 +106,14 @@ mk_hash_element(const void *key, size_t key_len, const void *p)
* @unittest: 1603
*/
void *
-Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p)
+Curl_hash_add(struct Curl_hash *h, void *key, size_t key_len, void *p)
{
- struct curl_hash_element *he;
- struct curl_llist_element *le;
- struct curl_llist *l = FETCH_LIST(h, key, key_len);
+ struct Curl_hash_element *he;
+ struct Curl_llist_element *le;
+ struct Curl_llist *l = FETCH_LIST(h, key, key_len);
for(le = l->head; le; le = le->next) {
- he = (struct curl_hash_element *) le->ptr;
+ he = (struct Curl_hash_element *) le->ptr;
if(h->comp_func(he->key, he->key_len, key, key_len)) {
Curl_llist_remove(l, le, (void *)h);
--h->size;
@@ -136,13 +136,13 @@ Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p)
*
* @unittest: 1603
*/
-int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len)
+int Curl_hash_delete(struct Curl_hash *h, void *key, size_t key_len)
{
- struct curl_llist_element *le;
- struct curl_llist *l = FETCH_LIST(h, key, key_len);
+ struct Curl_llist_element *le;
+ struct Curl_llist *l = FETCH_LIST(h, key, key_len);
for(le = l->head; le; le = le->next) {
- struct curl_hash_element *he = le->ptr;
+ struct Curl_hash_element *he = le->ptr;
if(h->comp_func(he->key, he->key_len, key, key_len)) {
Curl_llist_remove(l, le, (void *) h);
--h->size;
@@ -157,15 +157,15 @@ int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len)
* @unittest: 1603
*/
void *
-Curl_hash_pick(struct curl_hash *h, void *key, size_t key_len)
+Curl_hash_pick(struct Curl_hash *h, void *key, size_t key_len)
{
- struct curl_llist_element *le;
- struct curl_llist *l;
+ struct Curl_llist_element *le;
+ struct Curl_llist *l;
if(h) {
l = FETCH_LIST(h, key, key_len);
for(le = l->head; le; le = le->next) {
- struct curl_hash_element *he = le->ptr;
+ struct Curl_hash_element *he = le->ptr;
if(h->comp_func(he->key, he->key_len, key, key_len)) {
return he->ptr;
}
@@ -177,17 +177,17 @@ Curl_hash_pick(struct curl_hash *h, void *key, size_t key_len)
#if defined(DEBUGBUILD) && defined(AGGRESIVE_TEST)
void
-Curl_hash_apply(curl_hash *h, void *user,
+Curl_hash_apply(Curl_hash *h, void *user,
void (*cb)(void *user, void *ptr))
{
- struct curl_llist_element *le;
+ struct Curl_llist_element *le;
int i;
for(i = 0; i < h->slots; ++i) {
for(le = (h->table[i])->head;
le;
le = le->next) {
- curl_hash_element *el = le->ptr;
+ Curl_hash_element *el = le->ptr;
cb(user, el->ptr);
}
}
@@ -202,7 +202,7 @@ Curl_hash_apply(curl_hash *h, void *user,
* @unittest: 1603
*/
void
-Curl_hash_destroy(struct curl_hash *h)
+Curl_hash_destroy(struct Curl_hash *h)
{
int i;
@@ -220,19 +220,19 @@ Curl_hash_destroy(struct curl_hash *h)
* @unittest: 1602
*/
void
-Curl_hash_clean(struct curl_hash *h)
+Curl_hash_clean(struct Curl_hash *h)
{
Curl_hash_clean_with_criterium(h, NULL, NULL);
}
/* Cleans all entries that pass the comp function criteria. */
void
-Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
+Curl_hash_clean_with_criterium(struct Curl_hash *h, void *user,
int (*comp)(void *, void *))
{
- struct curl_llist_element *le;
- struct curl_llist_element *lnext;
- struct curl_llist *list;
+ struct Curl_llist_element *le;
+ struct Curl_llist_element *lnext;
+ struct Curl_llist *list;
int i;
if(!h)
@@ -242,7 +242,7 @@ Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
list = &h->table[i];
le = list->head; /* get first list entry */
while(le) {
- struct curl_hash_element *he = le->ptr;
+ struct Curl_hash_element *he = le->ptr;
lnext = le->next;
/* ask the callback function if we shall remove this entry or not */
if(comp == NULL || comp(user, he->ptr)) {
@@ -277,18 +277,18 @@ size_t Curl_str_key_compare(void *k1, size_t key1_len,
return 0;
}
-void Curl_hash_start_iterate(struct curl_hash *hash,
- struct curl_hash_iterator *iter)
+void Curl_hash_start_iterate(struct Curl_hash *hash,
+ struct Curl_hash_iterator *iter)
{
iter->hash = hash;
iter->slot_index = 0;
iter->current_element = NULL;
}
-struct curl_hash_element *
-Curl_hash_next_element(struct curl_hash_iterator *iter)
+struct Curl_hash_element *
+Curl_hash_next_element(struct Curl_hash_iterator *iter)
{
- struct curl_hash *h = iter->hash;
+ struct Curl_hash *h = iter->hash;
/* Get the next element in the current list, if any */
if(iter->current_element)
@@ -307,7 +307,7 @@ Curl_hash_next_element(struct curl_hash_iterator *iter)
}
if(iter->current_element) {
- struct curl_hash_element *he = iter->current_element->ptr;
+ struct Curl_hash_element *he = iter->current_element->ptr;
return he;
}
iter->current_element = NULL;
@@ -315,11 +315,11 @@ Curl_hash_next_element(struct curl_hash_iterator *iter)
}
#if 0 /* useful function for debugging hashes and their contents */
-void Curl_hash_print(struct curl_hash *h,
+void Curl_hash_print(struct Curl_hash *h,
void (*func)(void *))
{
- struct curl_hash_iterator iter;
- struct curl_hash_element *he;
+ struct Curl_hash_iterator iter;
+ struct Curl_hash_element *he;
int last_index = -1;
if(!h)
diff --git a/lib/hash.h b/lib/hash.h
index 558d0f47c..b7f828e07 100644
--- a/lib/hash.h
+++ b/lib/hash.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -41,59 +41,59 @@ typedef size_t (*comp_function) (void *key1,
void *key2,
size_t key2_len);
-typedef void (*curl_hash_dtor)(void *);
+typedef void (*Curl_hash_dtor)(void *);
-struct curl_hash {
- struct curl_llist *table;
+struct Curl_hash {
+ struct Curl_llist *table;
/* Hash function to be used for this hash table */
hash_function hash_func;
/* Comparator function to compare keys */
comp_function comp_func;
- curl_hash_dtor dtor;
+ Curl_hash_dtor dtor;
int slots;
size_t size;
};
-struct curl_hash_element {
- struct curl_llist_element list;
+struct Curl_hash_element {
+ struct Curl_llist_element list;
void *ptr;
size_t key_len;
char key[1]; /* allocated memory following the struct */
};
-struct curl_hash_iterator {
- struct curl_hash *hash;
+struct Curl_hash_iterator {
+ struct Curl_hash *hash;
int slot_index;
- struct curl_llist_element *current_element;
+ struct Curl_llist_element *current_element;
};
-int Curl_hash_init(struct curl_hash *h,
+int Curl_hash_init(struct Curl_hash *h,
int slots,
hash_function hfunc,
comp_function comparator,
- curl_hash_dtor dtor);
+ Curl_hash_dtor dtor);
-void *Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p);
-int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len);
-void *Curl_hash_pick(struct curl_hash *, void *key, size_t key_len);
-void Curl_hash_apply(struct curl_hash *h, void *user,
+void *Curl_hash_add(struct Curl_hash *h, void *key, size_t key_len, void *p);
+int Curl_hash_delete(struct Curl_hash *h, void *key, size_t key_len);
+void *Curl_hash_pick(struct Curl_hash *, void *key, size_t key_len);
+void Curl_hash_apply(struct Curl_hash *h, void *user,
void (*cb)(void *user, void *ptr));
#define Curl_hash_count(h) ((h)->size)
-void Curl_hash_destroy(struct curl_hash *h);
-void Curl_hash_clean(struct curl_hash *h);
-void Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
+void Curl_hash_destroy(struct Curl_hash *h);
+void Curl_hash_clean(struct Curl_hash *h);
+void Curl_hash_clean_with_criterium(struct Curl_hash *h, void *user,
int (*comp)(void *, void *));
size_t Curl_hash_str(void *key, size_t key_length, size_t slots_num);
size_t Curl_str_key_compare(void *k1, size_t key1_len, void *k2,
size_t key2_len);
-void Curl_hash_start_iterate(struct curl_hash *hash,
- struct curl_hash_iterator *iter);
-struct curl_hash_element *
-Curl_hash_next_element(struct curl_hash_iterator *iter);
+void Curl_hash_start_iterate(struct Curl_hash *hash,
+ struct Curl_hash_iterator *iter);
+struct Curl_hash_element *
+Curl_hash_next_element(struct Curl_hash_iterator *iter);
-void Curl_hash_print(struct curl_hash *h,
+void Curl_hash_print(struct Curl_hash *h,
void (*func)(void *));
diff --git a/lib/hmac.c b/lib/hmac.c
index c180b5963..dc1827878 100644
--- a/lib/hmac.c
+++ b/lib/hmac.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/hostasyn.c b/lib/hostasyn.c
index ed9190f4c..56a6fc2b7 100644
--- a/lib/hostasyn.c
+++ b/lib/hostasyn.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/hostcheck.c b/lib/hostcheck.c
index 9e0db05fa..0fef98b2a 100644
--- a/lib/hostcheck.c
+++ b/lib/hostcheck.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/hostcheck.h b/lib/hostcheck.h
index ee23e4366..47a33d04e 100644
--- a/lib/hostcheck.h
+++ b/lib/hostcheck.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/hostip.c b/lib/hostip.c
index dd5916e33..ab1f6df05 100644
--- a/lib/hostip.c
+++ b/lib/hostip.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -206,7 +206,7 @@ hostcache_timestamp_remove(void *datap, void *hc)
* Prune the DNS cache. This assumes that a lock has already been taken.
*/
static void
-hostcache_prune(struct curl_hash *hostcache, long cache_timeout, time_t now)
+hostcache_prune(struct Curl_hash *hostcache, long cache_timeout, time_t now)
{
struct hostcache_prune_data user;
@@ -843,7 +843,7 @@ static void freednsentry(void *freethis)
/*
* Curl_mk_dnscache() inits a new DNS cache and returns success/failure.
*/
-int Curl_mk_dnscache(struct curl_hash *hash)
+int Curl_mk_dnscache(struct Curl_hash *hash)
{
return Curl_hash_init(hash, 7, Curl_hash_str, Curl_str_key_compare,
freednsentry);
@@ -857,7 +857,7 @@ int Curl_mk_dnscache(struct curl_hash *hash)
*/
void Curl_hostcache_clean(struct Curl_easy *data,
- struct curl_hash *hash)
+ struct Curl_hash *hash)
{
if(data && data->share)
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
diff --git a/lib/hostip.h b/lib/hostip.h
index 374b06c85..724a03d7f 100644
--- a/lib/hostip.h
+++ b/lib/hostip.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -59,9 +59,9 @@ struct connectdata;
* Global DNS cache is general badness. Do not use. This will be removed in
* a future version. Use the share interface instead!
*
- * Returns a struct curl_hash pointer on success, NULL on failure.
+ * Returns a struct Curl_hash pointer on success, NULL on failure.
*/
-struct curl_hash *Curl_global_host_cache_init(void);
+struct Curl_hash *Curl_global_host_cache_init(void);
struct Curl_dns_entry {
struct Curl_addrinfo *addr;
@@ -128,7 +128,7 @@ void Curl_resolv_unlock(struct Curl_easy *data,
struct Curl_dns_entry *dns);
/* init a new dns cache and return success */
-int Curl_mk_dnscache(struct curl_hash *hash);
+int Curl_mk_dnscache(struct Curl_hash *hash);
/* prune old entries from the DNS cache */
void Curl_hostcache_prune(struct Curl_easy *data);
@@ -234,7 +234,7 @@ CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data,
/*
* Clean off entries from the cache
*/
-void Curl_hostcache_clean(struct Curl_easy *data, struct curl_hash *hash);
+void Curl_hostcache_clean(struct Curl_easy *data, struct Curl_hash *hash);
/*
* Populate the cache with specified entries from CURLOPT_RESOLVE.
diff --git a/lib/hostip4.c b/lib/hostip4.c
index eae941674..df83a2f12 100644
--- a/lib/hostip4.c
+++ b/lib/hostip4.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/hostip6.c b/lib/hostip6.c
index 11215758d..02b0ca298 100644
--- a/lib/hostip6.c
+++ b/lib/hostip6.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/hostsyn.c b/lib/hostsyn.c
index 9e31008d2..550b43a08 100644
--- a/lib/hostsyn.c
+++ b/lib/hostsyn.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/hsts.c b/lib/hsts.c
new file mode 100644
index 000000000..6f771284f
--- /dev/null
+++ b/lib/hsts.c
@@ -0,0 +1,522 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/*
+ * The Strict-Transport-Security header is defined in RFC 6797:
+ * https://tools.ietf.org/html/rfc6797
+ */
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_HSTS)
+#include <curl/curl.h>
+#include "urldata.h"
+#include "llist.h"
+#include "hsts.h"
+#include "curl_get_line.h"
+#include "strcase.h"
+#include "sendf.h"
+#include "strtoofft.h"
+#include "parsedate.h"
+#include "rand.h"
+#include "rename.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define MAX_HSTS_LINE 4095
+#define MAX_HSTS_HOSTLEN 256
+#define MAX_HSTS_HOSTLENSTR "256"
+#define MAX_HSTS_SUBLEN 4
+#define MAX_HSTS_SUBLENSTR "4"
+#define MAX_HSTS_DATELEN 64
+#define MAX_HSTS_DATELENSTR "64"
+
+#ifdef DEBUGBUILD
+/* to play well with debug builds, we can *set* a fixed time this will
+ return */
+time_t deltatime; /* allow for "adjustments" for unit test purposes */
+static time_t debugtime(void *unused)
+{
+ char *timestr = getenv("CURL_TIME");
+ (void)unused;
+ if(timestr) {
+ unsigned long val = strtol(timestr, NULL, 10) + deltatime;
+ return (time_t)val;
+ }
+ return time(NULL);
+}
+#define time(x) debugtime(x)
+#endif
+
+struct hsts *Curl_hsts_init(void)
+{
+ struct hsts *h = calloc(sizeof(struct hsts), 1);
+ if(h) {
+ Curl_llist_init(&h->list, NULL);
+ }
+ return h;
+}
+
+static void hsts_free(struct stsentry *e)
+{
+ free((char *)e->host);
+ free(e);
+}
+
+void Curl_hsts_cleanup(struct hsts **hp)
+{
+ struct hsts *h = *hp;
+ if(h) {
+ struct Curl_llist_element *e;
+ struct Curl_llist_element *n;
+ for(e = h->list.head; e; e = n) {
+ struct stsentry *sts = e->ptr;
+ n = e->next;
+ hsts_free(sts);
+ }
+ free(h->filename);
+ free(h);
+ *hp = NULL;
+ }
+}
+
+static struct stsentry *hsts_entry(void)
+{
+ return calloc(sizeof(struct stsentry), 1);
+}
+
+static CURLcode hsts_create(struct hsts *h,
+ const char *hostname,
+ bool subdomains,
+ curl_off_t expires)
+{
+ struct stsentry *sts = hsts_entry();
+ if(!sts)
+ return CURLE_OUT_OF_MEMORY;
+
+ sts->expires = expires;
+ sts->includeSubDomains = subdomains;
+ sts->host = strdup(hostname);
+ if(!sts->host) {
+ free(sts);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ Curl_llist_insert_next(&h->list, h->list.tail, sts, &sts->node);
+ return CURLE_OK;
+}
+
+CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname,
+ const char *header)
+{
+ const char *p = header;
+ curl_off_t expires = 0;
+ bool gotma = FALSE;
+ bool gotinc = FALSE;
+ bool subdomains = FALSE;
+ struct stsentry *sts;
+ time_t now = time(NULL);
+
+ do {
+ while(*p && ISSPACE(*p))
+ p++;
+ if(Curl_strncasecompare("max-age=", p, 8)) {
+ bool quoted = FALSE;
+ CURLofft offt;
+ char *endp;
+
+ if(gotma)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+
+ p += 8;
+ while(*p && ISSPACE(*p))
+ p++;
+ if(*p == '\"') {
+ p++;
+ quoted = TRUE;
+ }
+ offt = curlx_strtoofft(p, &endp, 10, &expires);
+ if(offt == CURL_OFFT_FLOW)
+ expires = CURL_OFF_T_MAX;
+ else if(offt)
+ /* invalid max-age */
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ p = endp;
+ if(quoted) {
+ if(*p != '\"')
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ p++;
+ }
+ gotma = TRUE;
+ }
+ else if(Curl_strncasecompare("includesubdomains", p, 17)) {
+ if(gotinc)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ subdomains = TRUE;
+ p += 17;
+ gotinc = TRUE;
+ }
+ else {
+ /* unknown directive, do a lame attempt to skip */
+ while(*p && (*p != ';'))
+ p++;
+ }
+
+ while(*p && ISSPACE(*p))
+ p++;
+ if(*p == ';')
+ p++;
+ } while (*p);
+
+ if(!gotma)
+ /* max-age is mandatory */
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+
+ if(!expires) {
+ /* remove the entry if present verbatim (without subdomain match) */
+ sts = Curl_hsts(h, hostname, FALSE);
+ if(sts) {
+ Curl_llist_remove(&h->list, &sts->node, NULL);
+ hsts_free(sts);
+ }
+ return CURLE_OK;
+ }
+
+ if(CURL_OFF_T_MAX - now < expires)
+ /* would overflow, use maximum value */
+ expires = CURL_OFF_T_MAX;
+ else
+ expires += now;
+
+ /* check if it already exists */
+ sts = Curl_hsts(h, hostname, FALSE);
+ if(sts) {
+ /* just update these fields */
+ sts->expires = expires;
+ sts->includeSubDomains = subdomains;
+ }
+ else
+ return hsts_create(h, hostname, subdomains, expires);
+
+ return CURLE_OK;
+}
+
+/*
+ * Return TRUE if the given host name is currently an HSTS one.
+ *
+ * The 'subdomain' argument tells the function if subdomain matching should be
+ * attempted.
+ */
+struct stsentry *Curl_hsts(struct hsts *h, const char *hostname,
+ bool subdomain)
+{
+ if(h) {
+ time_t now = time(NULL);
+ size_t hlen = strlen(hostname);
+ struct Curl_llist_element *e;
+ struct Curl_llist_element *n;
+ for(e = h->list.head; e; e = n) {
+ struct stsentry *sts = e->ptr;
+ n = e->next;
+ if(sts->expires <= now) {
+ /* remove expired entries */
+ Curl_llist_remove(&h->list, &sts->node, NULL);
+ hsts_free(sts);
+ continue;
+ }
+ if(subdomain && sts->includeSubDomains) {
+ size_t ntail = strlen(sts->host);
+ if(ntail < hlen) {
+ size_t offs = hlen - ntail;
+ if((hostname[offs-1] == '.') &&
+ Curl_strncasecompare(&hostname[offs], sts->host, ntail))
+ return sts;
+ }
+ }
+ if(Curl_strcasecompare(hostname, sts->host))
+ return sts;
+ }
+ }
+ return NULL; /* no match */
+}
+
+/*
+ * Send this HSTS entry to the write callback.
+ */
+static CURLcode hsts_push(struct Curl_easy *data,
+ struct curl_index *i,
+ struct stsentry *sts,
+ bool *stop)
+{
+ struct curl_hstsentry e;
+ CURLSTScode sc;
+ struct tm stamp;
+ CURLcode result;
+
+ e.name = (char *)sts->host;
+ e.namelen = strlen(sts->host);
+ e.includeSubDomains = sts->includeSubDomains;
+
+ result = Curl_gmtime(sts->expires, &stamp);
+ if(result)
+ return result;
+
+ msnprintf(e.expire, sizeof(e.expire), "%d%02d%02d %02d:%02d:%02d",
+ stamp.tm_year + 1900, stamp.tm_mon + 1, stamp.tm_mday,
+ stamp.tm_hour, stamp.tm_min, stamp.tm_sec);
+
+ sc = data->set.hsts_write(data, &e, i,
+ data->set.hsts_write_userp);
+ *stop = (sc != CURLSTS_OK);
+ return sc == CURLSTS_FAIL ? CURLE_BAD_FUNCTION_ARGUMENT : CURLE_OK;
+}
+
+/*
+ * Write this single hsts entry to a single output line
+ */
+static CURLcode hsts_out(struct stsentry *sts, FILE *fp)
+{
+ struct tm stamp;
+ CURLcode result = Curl_gmtime(sts->expires, &stamp);
+ if(result)
+ return result;
+
+ fprintf(fp, "%s%s \"%d%02d%02d %02d:%02d:%02d\"\n",
+ sts->includeSubDomains ? ".": "", sts->host,
+ stamp.tm_year + 1900, stamp.tm_mon + 1, stamp.tm_mday,
+ stamp.tm_hour, stamp.tm_min, stamp.tm_sec);
+ return CURLE_OK;
+}
+
+
+/*
+ * Curl_https_save() writes the HSTS cache to file and callback.
+ */
+CURLcode Curl_hsts_save(struct Curl_easy *data, struct hsts *h,
+ const char *file)
+{
+ struct Curl_llist_element *e;
+ struct Curl_llist_element *n;
+ CURLcode result = CURLE_OK;
+ FILE *out;
+ char *tempstore;
+ unsigned char randsuffix[9];
+
+ if(!h)
+ /* no cache activated */
+ return CURLE_OK;
+
+ /* if not new name is given, use the one we stored from the load */
+ if(!file && h->filename)
+ file = h->filename;
+
+ if((h->flags & CURLHSTS_READONLYFILE) || !file || !file[0])
+ /* marked as read-only, no file or zero length file name */
+ goto skipsave;
+
+ if(Curl_rand_hex(data, randsuffix, sizeof(randsuffix)))
+ return CURLE_FAILED_INIT;
+
+ tempstore = aprintf("%s.%s.tmp", file, randsuffix);
+ if(!tempstore)
+ return CURLE_OUT_OF_MEMORY;
+
+ out = fopen(tempstore, FOPEN_WRITETEXT);
+ if(!out)
+ result = CURLE_WRITE_ERROR;
+ else {
+ fputs("# Your HSTS cache. https://curl.se/docs/hsts.html\n"
+ "# This file was generated by libcurl! Edit at your own risk.\n",
+ out);
+ for(e = h->list.head; e; e = n) {
+ struct stsentry *sts = e->ptr;
+ n = e->next;
+ result = hsts_out(sts, out);
+ if(result)
+ break;
+ }
+ fclose(out);
+ if(!result && Curl_rename(tempstore, file))
+ result = CURLE_WRITE_ERROR;
+
+ if(result)
+ unlink(tempstore);
+ }
+ free(tempstore);
+ skipsave:
+ if(data->set.hsts_write) {
+ /* if there's a write callback */
+ struct curl_index i; /* count */
+ i.total = h->list.size;
+ i.index = 0;
+ for(e = h->list.head; e; e = n) {
+ struct stsentry *sts = e->ptr;
+ bool stop;
+ n = e->next;
+ result = hsts_push(data, &i, sts, &stop);
+ if(result || stop)
+ break;
+ i.index++;
+ }
+ }
+ return result;
+}
+
+/* only returns SERIOUS errors */
+static CURLcode hsts_add(struct hsts *h, char *line)
+{
+ /* Example lines:
+ example.com "20191231 10:00:00"
+ .example.net "20191231 10:00:00"
+ */
+ char host[MAX_HSTS_HOSTLEN + 1];
+ char date[MAX_HSTS_DATELEN + 1];
+ int rc;
+
+ rc = sscanf(line,
+ "%" MAX_HSTS_HOSTLENSTR "s \"%" MAX_HSTS_DATELENSTR "[^\"]\"",
+ host, date);
+ if(2 == rc) {
+ time_t expires = Curl_getdate_capped(date);
+ CURLcode result;
+ char *p = host;
+ bool subdomain = FALSE;
+ if(p[0] == '.') {
+ p++;
+ subdomain = TRUE;
+ }
+ result = hsts_create(h, p, subdomain, expires);
+ if(result)
+ return result;
+ }
+
+ return CURLE_OK;
+}
+
+/*
+ * Load HSTS data from callback.
+ *
+ */
+static CURLcode hsts_pull(struct Curl_easy *data, struct hsts *h)
+{
+ /* if the HSTS read callback is set, use it */
+ if(data->set.hsts_read) {
+ CURLSTScode sc;
+ DEBUGASSERT(h);
+ do {
+ char buffer[257];
+ struct curl_hstsentry e;
+ e.name = buffer;
+ e.namelen = sizeof(buffer)-1;
+ e.includeSubDomains = FALSE; /* default */
+ e.expire[0] = 0;
+ e.name[0] = 0; /* just to make it clean */
+ sc = data->set.hsts_read(data, &e, data->set.hsts_read_userp);
+ if(sc == CURLSTS_OK) {
+ time_t expires;
+ CURLcode result;
+ if(!e.name[0])
+ /* bail out if no name was stored */
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ if(e.expire[0])
+ expires = Curl_getdate_capped(e.expire);
+ else
+ expires = TIME_T_MAX; /* the end of time */
+ result = hsts_create(h, e.name, e.includeSubDomains, expires);
+ if(result)
+ return result;
+ }
+ else if(sc == CURLSTS_FAIL)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ } while(sc == CURLSTS_OK);
+ }
+ return CURLE_OK;
+}
+
+/*
+ * Load the HSTS cache from the given file. The text based line-oriented file
+ * format is documented here:
+ * https://github.com/curl/curl/wiki/HSTS
+ *
+ * This function only returns error on major problems that prevents hsts
+ * handling to work completely. It will ignore individual syntactical errors
+ * etc.
+ */
+static CURLcode hsts_load(struct hsts *h, const char *file)
+{
+ CURLcode result = CURLE_OK;
+ char *line = NULL;
+ FILE *fp;
+
+ /* we need a private copy of the file name so that the hsts cache file
+ name survives an easy handle reset */
+ free(h->filename);
+ h->filename = strdup(file);
+ if(!h->filename)
+ return CURLE_OUT_OF_MEMORY;
+
+ fp = fopen(file, FOPEN_READTEXT);
+ if(fp) {
+ line = malloc(MAX_HSTS_LINE);
+ if(!line)
+ goto fail;
+ while(Curl_get_line(line, MAX_HSTS_LINE, fp)) {
+ char *lineptr = line;
+ while(*lineptr && ISBLANK(*lineptr))
+ lineptr++;
+ if(*lineptr == '#')
+ /* skip commented lines */
+ continue;
+
+ hsts_add(h, lineptr);
+ }
+ free(line); /* free the line buffer */
+ fclose(fp);
+ }
+ return result;
+
+ fail:
+ Curl_safefree(h->filename);
+ fclose(fp);
+ return CURLE_OUT_OF_MEMORY;
+}
+
+/*
+ * Curl_hsts_loadfile() loads HSTS from file
+ */
+CURLcode Curl_hsts_loadfile(struct Curl_easy *data,
+ struct hsts *h, const char *file)
+{
+ DEBUGASSERT(h);
+ (void)data;
+ return hsts_load(h, file);
+}
+
+/*
+ * Curl_hsts_loadcb() loads HSTS from callback
+ */
+CURLcode Curl_hsts_loadcb(struct Curl_easy *data, struct hsts *h)
+{
+ return hsts_pull(data, h);
+}
+
+#endif /* CURL_DISABLE_HTTP || USE_HSTS */
diff --git a/lib/hsts.h b/lib/hsts.h
new file mode 100644
index 000000000..ae5db74a2
--- /dev/null
+++ b/lib/hsts.h
@@ -0,0 +1,65 @@
+#ifndef HEADER_CURL_HSTS_H
+#define HEADER_CURL_HSTS_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_HSTS)
+#include <curl/curl.h>
+#include "llist.h"
+
+#ifdef DEBUGBUILD
+extern time_t deltatime;
+#endif
+
+struct stsentry {
+ struct Curl_llist_element node;
+ const char *host;
+ bool includeSubDomains;
+ time_t expires; /* the timestamp of this entry's expiry */
+};
+
+/* The HSTS cache. Needs to be able to tailmatch host names. */
+struct hsts {
+ struct Curl_llist list;
+ char *filename;
+ unsigned int flags;
+};
+
+struct hsts *Curl_hsts_init(void);
+void Curl_hsts_cleanup(struct hsts **hp);
+CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname,
+ const char *sts);
+struct stsentry *Curl_hsts(struct hsts *h, const char *hostname,
+ bool subdomain);
+CURLcode Curl_hsts_save(struct Curl_easy *data, struct hsts *h,
+ const char *file);
+CURLcode Curl_hsts_loadfile(struct Curl_easy *data,
+ struct hsts *h, const char *file);
+CURLcode Curl_hsts_loadcb(struct Curl_easy *data,
+ struct hsts *h);
+#else
+#define Curl_hsts_cleanup(x)
+#define Curl_hsts_loadcb(x,y)
+#define Curl_hsts_save(x,y,z)
+#endif /* CURL_DISABLE_HTTP || USE_HSTS */
+#endif /* HEADER_CURL_HSTS_H */
diff --git a/lib/http.c b/lib/http.c
index b8db35acc..e23a4a4fd 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -77,6 +77,7 @@
#include "connect.h"
#include "strdup.h"
#include "altsvc.h"
+#include "hsts.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -125,6 +126,7 @@ const struct Curl_handler Curl_handler_http = {
ZERO_NULL, /* connection_check */
PORT_HTTP, /* defport */
CURLPROTO_HTTP, /* protocol */
+ CURLPROTO_HTTP, /* family */
PROTOPT_CREDSPERREQUEST | /* flags */
PROTOPT_USERPWDCTRL
};
@@ -151,6 +153,7 @@ const struct Curl_handler Curl_handler_https = {
ZERO_NULL, /* connection_check */
PORT_HTTPS, /* defport */
CURLPROTO_HTTPS, /* protocol */
+ CURLPROTO_HTTP, /* family */
PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN_NPN | /* flags */
PROTOPT_USERPWDCTRL
};
@@ -162,14 +165,14 @@ static CURLcode http_setup_conn(struct connectdata *conn)
during this request */
struct HTTP *http;
struct Curl_easy *data = conn->data;
- DEBUGASSERT(data->req.protop == NULL);
+ DEBUGASSERT(data->req.p.http == NULL);
http = calloc(1, sizeof(struct HTTP));
if(!http)
return CURLE_OUT_OF_MEMORY;
Curl_mime_initpart(&http->form, conn->data);
- data->req.protop = http;
+ data->req.p.http = http;
if(data->set.httpversion == CURL_HTTP_VERSION_3) {
if(conn->handler->flags & PROTOPT_SSL)
@@ -425,7 +428,7 @@ static bool pickoneauth(struct auth *pick, unsigned long mask)
static CURLcode http_perhapsrewind(struct connectdata *conn)
{
struct Curl_easy *data = conn->data;
- struct HTTP *http = data->req.protop;
+ struct HTTP *http = data->req.p.http;
curl_off_t bytessent;
curl_off_t expectsend = -1; /* default is unknown */
@@ -1109,7 +1112,7 @@ static size_t readmoredata(char *buffer,
void *userp)
{
struct connectdata *conn = (struct connectdata *)userp;
- struct HTTP *http = conn->data->req.protop;
+ struct HTTP *http = conn->data->req.p.http;
size_t fullsize = size * nitems;
if(!http->postsize)
@@ -1167,7 +1170,7 @@ CURLcode Curl_buffer_send(struct dynbuf *in,
char *ptr;
size_t size;
struct Curl_easy *data = conn->data;
- struct HTTP *http = data->req.protop;
+ struct HTTP *http = data->req.p.http;
size_t sendsize;
curl_socket_t sockfd;
size_t headersize;
@@ -1252,16 +1255,12 @@ CURLcode Curl_buffer_send(struct dynbuf *in,
size_t headlen = (size_t)amount>headersize ? headersize : (size_t)amount;
size_t bodylen = amount - headlen;
- if(data->set.verbose) {
- /* this data _may_ contain binary stuff */
- Curl_debug(data, CURLINFO_HEADER_OUT, ptr, headlen);
- if(bodylen) {
- /* there was body data sent beyond the initial header part, pass that
- on to the debug callback too */
- Curl_debug(data, CURLINFO_DATA_OUT,
- ptr + headlen, bodylen);
- }
- }
+ /* this data _may_ contain binary stuff */
+ Curl_debug(data, CURLINFO_HEADER_OUT, ptr, headlen);
+ if(bodylen)
+ /* there was body data sent beyond the initial header part, pass that on
+ to the debug callback too */
+ Curl_debug(data, CURLINFO_DATA_OUT, ptr + headlen, bodylen);
/* 'amount' can never be a very large value here so typecasting it so a
signed 31 bit value should not cause problems even if ssize_t is
@@ -1353,7 +1352,7 @@ Curl_compareheader(const char *headerline, /* line to check */
/* pass the header */
start = &headerline[hlen];
- /* pass all white spaces */
+ /* pass all whitespace */
while(*start && ISSPACE(*start))
start++;
@@ -1517,7 +1516,7 @@ CURLcode Curl_http_done(struct connectdata *conn,
CURLcode status, bool premature)
{
struct Curl_easy *data = conn->data;
- struct HTTP *http = data->req.protop;
+ struct HTTP *http = data->req.p.http;
/* Clear multipass flag. If authentication isn't done yet, then it will get
* a chance to be set back to true when we output the next auth header */
@@ -1978,7 +1977,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
return result;
}
}
- http = data->req.protop;
+ http = data->req.p.http;
DEBUGASSERT(http);
if(!data->state.this_is_a_follow) {
@@ -2516,7 +2515,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
if(result)
return result;
-#ifdef USE_ALTSVC
+#ifndef CURL_DISABLE_ALTSVC
if(conn->bits.altused && !Curl_checkheaders(conn, "Alt-Used")) {
altused = aprintf("Alt-Used: %s:%d\r\n",
conn->conn_to_host.name, conn->conn_to_port);
@@ -2871,20 +2870,24 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
}
else {
if(postsize) {
+ char chunk[16];
/* Append the POST data chunky-style */
- result = Curl_dyn_addf(&req, "%x\r\n", (int)postsize);
+ msnprintf(chunk, sizeof(chunk), "%x\r\n", (int)postsize);
+ result = Curl_dyn_add(&req, chunk);
if(!result) {
+ included_body = postsize + strlen(chunk);
result = Curl_dyn_addn(&req, data->set.postfields,
(size_t)postsize);
if(!result)
result = Curl_dyn_add(&req, "\r\n");
- included_body = postsize + 2;
+ included_body += 2;
}
}
- if(!result)
+ if(!result) {
result = Curl_dyn_add(&req, "\x30\x0d\x0a\x0d\x0a");
- /* 0 CR LF CR LF */
- included_body += 5;
+ /* 0 CR LF CR LF */
+ included_body += 5;
+ }
}
if(result)
return result;
@@ -3531,10 +3534,8 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
k->keepon &= ~KEEP_RECV;
}
- if(data->set.verbose)
- Curl_debug(data, CURLINFO_HEADER_IN,
- str_start, headerlen);
- break; /* exit header line loop */
+ Curl_debug(data, CURLINFO_HEADER_IN, str_start, headerlen);
+ break; /* exit header line loop */
}
/* We continue reading headers, reset the line-based header */
@@ -3990,7 +3991,24 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
}
}
}
-#ifdef USE_ALTSVC
+
+#ifdef USE_HSTS
+ /* If enabled, the header is incoming and this is over HTTPS */
+ else if(data->hsts && checkprefix("Strict-Transport-Security:", headp) &&
+ (conn->handler->flags & PROTOPT_SSL)) {
+ CURLcode check =
+ Curl_hsts_parse(data->hsts, data->state.up.hostname,
+ &headp[ sizeof("Strict-Transport-Security:") -1 ]);
+ if(check)
+ infof(data, "Illegal STS header skipped\n");
+#ifdef DEBUGBUILD
+ else
+ infof(data, "Parsed STS header fine (%zu entries)\n",
+ data->hsts->list.size);
+#endif
+ }
+#endif
+#ifndef CURL_DISABLE_ALTSVC
/* If enabled, the header is incoming and this is over HTTPS */
else if(data->asi && checkprefix("Alt-Svc:", headp) &&
((conn->handler->flags & PROTOPT_SSL) ||
@@ -4025,9 +4043,8 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
if(data->set.include_header)
writetype |= CLIENTWRITE_BODY;
- if(data->set.verbose)
- Curl_debug(data, CURLINFO_HEADER_IN, headp,
- Curl_dyn_len(&data->state.headerb));
+ Curl_debug(data, CURLINFO_HEADER_IN, headp,
+ Curl_dyn_len(&data->state.headerb));
result = Curl_client_write(conn, writetype, headp,
Curl_dyn_len(&data->state.headerb));
diff --git a/lib/http.h b/lib/http.h
index a522de30c..ae03dfa79 100644
--- a/lib/http.h
+++ b/lib/http.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/http2.c b/lib/http2.c
index 222ff1bb7..03e739da1 100644
--- a/lib/http2.c
+++ b/lib/http2.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -257,7 +257,7 @@ static unsigned int http2_conncheck(struct connectdata *check,
/* called from http_setup_conn */
void Curl_http2_setup_req(struct Curl_easy *data)
{
- struct HTTP *http = data->req.protop;
+ struct HTTP *http = data->req.p.http;
http->bodystarted = FALSE;
http->status_code = -1;
http->pausedata = NULL;
@@ -300,6 +300,7 @@ static const struct Curl_handler Curl_handler_http2 = {
http2_conncheck, /* connection_check */
PORT_HTTP, /* defport */
CURLPROTO_HTTP, /* protocol */
+ CURLPROTO_HTTP, /* family */
PROTOPT_STREAM /* flags */
};
@@ -321,6 +322,7 @@ static const struct Curl_handler Curl_handler_http2_ssl = {
http2_conncheck, /* connection_check */
PORT_HTTP, /* defport */
CURLPROTO_HTTPS, /* protocol */
+ CURLPROTO_HTTP, /* family */
PROTOPT_SSL | PROTOPT_STREAM /* flags */
};
@@ -391,7 +393,7 @@ char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num)
if(!h || !GOOD_EASY_HANDLE(h->data))
return NULL;
else {
- struct HTTP *stream = h->data->req.protop;
+ struct HTTP *stream = h->data->req.p.http;
if(num < stream->push_headers_used)
return stream->push_headers[num];
}
@@ -413,7 +415,7 @@ char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header)
!strcmp(header, ":") || strchr(header + 1, ':'))
return NULL;
else {
- struct HTTP *stream = h->data->req.protop;
+ struct HTTP *stream = h->data->req.p.http;
size_t len = strlen(header);
size_t i;
for(i = 0; i<stream->push_headers_used; i++) {
@@ -460,7 +462,7 @@ static struct Curl_easy *duphandle(struct Curl_easy *data)
(void)Curl_close(&second);
}
else {
- second->req.protop = http;
+ second->req.p.http = http;
Curl_dyn_init(&http->header_recvbuf, DYN_H2_HEADERS);
Curl_http2_setup_req(second);
second->state.stream_weight = data->state.stream_weight;
@@ -537,7 +539,7 @@ static int push_promise(struct Curl_easy *data,
/* ask the application */
H2BUGF(infof(data, "Got PUSH_PROMISE, ask application!\n"));
- stream = data->req.protop;
+ stream = data->req.p.http;
if(!stream) {
failf(data, "Internal NULL stream!\n");
(void)Curl_close(&newhandle);
@@ -567,13 +569,13 @@ static int push_promise(struct Curl_easy *data,
if(rv) {
DEBUGASSERT((rv > CURL_PUSH_OK) && (rv <= CURL_PUSH_ERROROUT));
/* denied, kill off the new handle again */
- http2_stream_free(newhandle->req.protop);
- newhandle->req.protop = NULL;
+ http2_stream_free(newhandle->req.p.http);
+ newhandle->req.p.http = NULL;
(void)Curl_close(&newhandle);
goto fail;
}
- newstream = newhandle->req.protop;
+ newstream = newhandle->req.p.http;
newstream->stream_id = frame->promised_stream_id;
newhandle->req.maxdownload = -1;
newhandle->req.size = -1;
@@ -583,8 +585,8 @@ static int push_promise(struct Curl_easy *data,
rc = Curl_multi_add_perform(data->multi, newhandle, conn);
if(rc) {
infof(data, "failed to add handle to multi\n");
- http2_stream_free(newhandle->req.protop);
- newhandle->req.protop = NULL;
+ http2_stream_free(newhandle->req.p.http);
+ newhandle->req.p.http = NULL;
Curl_close(&newhandle);
rv = CURL_PUSH_DENY;
goto fail;
@@ -667,7 +669,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
return 0;
}
- stream = data_s->req.protop;
+ stream = data_s->req.p.http;
if(!stream) {
H2BUGF(infof(data_s, "No proto pointer for stream: %x\n",
stream_id));
@@ -783,7 +785,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
internal error more than anything else! */
return NGHTTP2_ERR_CALLBACK_FAILURE;
- stream = data_s->req.protop;
+ stream = data_s->req.p.http;
if(!stream)
return NGHTTP2_ERR_CALLBACK_FAILURE;
@@ -849,7 +851,7 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
}
H2BUGF(infof(data_s, "on_stream_close(), %s (err %d), stream %u\n",
nghttp2_http2_strerror(error_code), error_code, stream_id));
- stream = data_s->req.protop;
+ stream = data_s->req.p.http;
if(!stream)
return NGHTTP2_ERR_CALLBACK_FAILURE;
@@ -894,7 +896,7 @@ static int on_begin_headers(nghttp2_session *session,
return 0;
}
- stream = data_s->req.protop;
+ stream = data_s->req.p.http;
if(!stream || !stream->bodystarted) {
return 0;
}
@@ -952,7 +954,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
internal error more than anything else! */
return NGHTTP2_ERR_CALLBACK_FAILURE;
- stream = data_s->req.protop;
+ stream = data_s->req.p.http;
if(!stream) {
failf(data_s, "Internal NULL stream! 5\n");
return NGHTTP2_ERR_CALLBACK_FAILURE;
@@ -1100,7 +1102,7 @@ static ssize_t data_source_read_callback(nghttp2_session *session,
internal error more than anything else! */
return NGHTTP2_ERR_CALLBACK_FAILURE;
- stream = data_s->req.protop;
+ stream = data_s->req.p.http;
if(!stream)
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
@@ -1161,7 +1163,7 @@ static void populate_settings(struct connectdata *conn,
void Curl_http2_done(struct Curl_easy *data, bool premature)
{
- struct HTTP *http = data->req.protop;
+ struct HTTP *http = data->req.p.http;
struct http_conn *httpc = &data->conn->proto.httpc;
/* there might be allocated resources done before this got the 'h2' pointer
@@ -1207,13 +1209,6 @@ void Curl_http2_done(struct Curl_easy *data, bool premature)
}
http->stream_id = 0;
}
-
- if(0 == nghttp2_session_check_request_allowed(httpc->h2)) {
- /* No more requests are allowed in the current session, so the connection
- may not be reused. This is set when a GOAWAY frame has been received or
- when the limit of stream identifiers has been reached. */
- connclose(data->conn, "http/2: No new requests allowed");
- }
}
/*
@@ -1288,7 +1283,7 @@ CURLcode Curl_http2_request_upgrade(struct dynbuf *req,
binlen = nghttp2_pack_settings_payload(binsettings, H2_BINSETTINGS_LEN,
httpc->local_settings,
httpc->local_settings_num);
- if(!binlen) {
+ if(binlen <= 0) {
failf(conn->data, "nghttp2 unexpectedly failed on pack_settings_payload");
Curl_dyn_free(req);
return CURLE_FAILED_INIT;
@@ -1371,6 +1366,14 @@ static int h2_process_pending_input(struct connectdata *conn,
return -1;
}
+ if(nghttp2_session_check_request_allowed(httpc->h2) == 0) {
+ /* No more requests are allowed in the current session, so
+ the connection may not be reused. This is set when a
+ GOAWAY frame has been received or when the limit of stream
+ identifiers has been reached. */
+ connclose(conn, "http/2: No new requests allowed");
+ }
+
if(should_close_session(httpc)) {
H2BUGF(infof(data,
"h2_process_pending_input: nothing to do in this session\n"));
@@ -1383,7 +1386,6 @@ static int h2_process_pending_input(struct connectdata *conn,
}
return -1;
}
-
return 0;
}
@@ -1398,7 +1400,7 @@ CURLcode Curl_http2_done_sending(struct connectdata *conn)
(conn->handler == &Curl_handler_http2)) {
/* make sure this is only attempted for HTTP/2 transfers */
- struct HTTP *stream = conn->data->req.protop;
+ struct HTTP *stream = conn->data->req.p.http;
struct http_conn *httpc = &conn->proto.httpc;
nghttp2_session *h2 = httpc->h2;
@@ -1494,8 +1496,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
break;
len = lf + 1 - trailp;
- if(data->set.verbose)
- Curl_debug(data, CURLINFO_HEADER_IN, trailp, len);
+ Curl_debug(data, CURLINFO_HEADER_IN, trailp, len);
/* pass the trailers one by one to the callback */
result = Curl_client_write(conn, CLIENTWRITE_HEADER, trailp, len);
if(result) {
@@ -1522,7 +1523,7 @@ static void h2_pri_spec(struct Curl_easy *data,
nghttp2_priority_spec *pri_spec)
{
struct HTTP *depstream = (data->set.stream_depends_on?
- data->set.stream_depends_on->req.protop:NULL);
+ data->set.stream_depends_on->req.p.http:NULL);
int32_t depstream_id = depstream? depstream->stream_id:0;
nghttp2_priority_spec_init(pri_spec, depstream_id, data->set.stream_weight,
data->set.stream_depends_e);
@@ -1539,7 +1540,7 @@ static void h2_pri_spec(struct Curl_easy *data,
static int h2_session_send(struct Curl_easy *data,
nghttp2_session *h2)
{
- struct HTTP *stream = data->req.protop;
+ struct HTTP *stream = data->req.p.http;
if((data->set.stream_weight != data->state.stream_weight) ||
(data->set.stream_depends_e != data->state.stream_depends_e) ||
(data->set.stream_depends_on != data->state.stream_depends_on) ) {
@@ -1564,12 +1565,10 @@ static int h2_session_send(struct Curl_easy *data,
static ssize_t http2_recv(struct connectdata *conn, int sockindex,
char *mem, size_t len, CURLcode *err)
{
- CURLcode result = CURLE_OK;
- ssize_t rv;
ssize_t nread;
struct http_conn *httpc = &conn->proto.httpc;
struct Curl_easy *data = conn->data;
- struct HTTP *stream = data->req.protop;
+ struct HTTP *stream = data->req.p.http;
(void)sockindex; /* we always do HTTP2 on sockindex 0 */
@@ -1632,8 +1631,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
/* We have paused nghttp2, but we have no pause data (see
on_data_chunk_recv). */
httpc->pause_stream_id = 0;
- if(h2_process_pending_input(conn, httpc, &result) != 0) {
- *err = result;
+ if(h2_process_pending_input(conn, httpc, err) != 0) {
return -1;
}
}
@@ -1661,8 +1659,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
frames, then we have to call it again with 0-length data.
Without this, on_stream_close callback will not be called,
and stream could be hanged. */
- if(h2_process_pending_input(conn, httpc, &result) != 0) {
- *err = result;
+ if(h2_process_pending_input(conn, httpc, err) != 0) {
return -1;
}
}
@@ -1688,7 +1685,6 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
return -1;
}
else {
- char *inbuf;
/* remember where to store incoming data for this stream and how big the
buffer is */
stream->mem = mem;
@@ -1697,16 +1693,15 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
if(httpc->inbuflen == 0) {
nread = ((Curl_recv *)httpc->recv_underlying)(
- conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result);
+ conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, err);
if(nread == -1) {
- if(result != CURLE_AGAIN)
+ if(*err != CURLE_AGAIN)
failf(data, "Failed receiving HTTP2 data");
else if(stream->closed)
/* received when the stream was already closed! */
return http2_handle_stream_close(conn, data, stream, err);
- *err = result;
return -1;
}
@@ -1719,47 +1714,18 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
H2BUGF(infof(data, "nread=%zd\n", nread));
httpc->inbuflen = nread;
- inbuf = httpc->inbuf;
+
+ DEBUGASSERT(httpc->nread_inbuf == 0);
}
else {
nread = httpc->inbuflen - httpc->nread_inbuf;
- inbuf = httpc->inbuf + httpc->nread_inbuf;
-
+ (void)nread; /* silence warning, used in debug */
H2BUGF(infof(data, "Use data left in connection buffer, nread=%zd\n",
nread));
}
- rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread);
- if(nghttp2_is_fatal((int)rv)) {
- failf(data, "nghttp2_session_mem_recv() returned %zd:%s\n",
- rv, nghttp2_strerror((int)rv));
- *err = CURLE_RECV_ERROR;
- return -1;
- }
- H2BUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", rv));
- if(nread == rv) {
- H2BUGF(infof(data, "All data in connection buffer processed\n"));
- httpc->inbuflen = 0;
- httpc->nread_inbuf = 0;
- }
- else {
- httpc->nread_inbuf += rv;
- H2BUGF(infof(data, "%zu bytes left in connection buffer\n",
- httpc->inbuflen - httpc->nread_inbuf));
- }
- /* Always send pending frames in nghttp2 session, because
- nghttp2_session_mem_recv() may queue new frame */
- rv = h2_session_send(data, httpc->h2);
- if(rv != 0) {
- *err = CURLE_SEND_ERROR;
- return -1;
- }
-
- if(should_close_session(httpc)) {
- H2BUGF(infof(data, "http2_recv: nothing to do in this session\n"));
- *err = CURLE_HTTP2;
+ if(h2_process_pending_input(conn, httpc, err) != 0)
return -1;
- }
}
if(stream->memlen) {
ssize_t retlen = stream->memlen;
@@ -1874,7 +1840,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
*/
int rv;
struct http_conn *httpc = &conn->proto.httpc;
- struct HTTP *stream = conn->data->req.protop;
+ struct HTTP *stream = conn->data->req.p.http;
nghttp2_nv *nva = NULL;
size_t nheader;
size_t i;
@@ -2104,7 +2070,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
if(acc > MAX_ACC) {
infof(conn->data, "http2_send: Warning: The cumulative length of all "
- "headers exceeds %zu bytes and that could cause the "
+ "headers exceeds %d bytes and that could cause the "
"stream to be rejected.\n", MAX_ACC);
}
}
@@ -2112,7 +2078,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
h2_pri_spec(conn->data, &pri_spec);
H2BUGF(infof(conn->data, "http2_send request allowed %d (easy handle %p)\n",
- nghttp2_session_check_request_allowed(h2), (void *)conn->data));
+ nghttp2_session_check_request_allowed(h2), (void *)conn->data));
switch(conn->data->state.httpreq) {
case HTTPREQ_POST:
@@ -2138,7 +2104,9 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
Curl_safefree(nva);
if(stream_id < 0) {
- H2BUGF(infof(conn->data, "http2_send() send error\n"));
+ H2BUGF(infof(conn->data,
+ "http2_send() nghttp2_submit_request error (%s)%d\n",
+ nghttp2_strerror(stream_id), stream_id));
*err = CURLE_SEND_ERROR;
return -1;
}
@@ -2148,10 +2116,13 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
stream->stream_id = stream_id;
/* this does not call h2_session_send() since there can not have been any
- * priority upodate since the nghttp2_submit_request() call above */
+ * priority update since the nghttp2_submit_request() call above */
rv = nghttp2_session_send(h2);
-
if(rv != 0) {
+ H2BUGF(infof(conn->data,
+ "http2_send() nghttp2_session_send error (%s)%d\n",
+ nghttp2_strerror(rv), rv));
+
*err = CURLE_SEND_ERROR;
return -1;
}
@@ -2183,7 +2154,7 @@ CURLcode Curl_http2_setup(struct connectdata *conn)
{
CURLcode result;
struct http_conn *httpc = &conn->proto.httpc;
- struct HTTP *stream = conn->data->req.protop;
+ struct HTTP *stream = conn->data->req.p.http;
DEBUGASSERT(conn->data->state.buffer);
@@ -2236,9 +2207,8 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
CURLcode result;
struct http_conn *httpc = &conn->proto.httpc;
int rv;
- ssize_t nproc;
struct Curl_easy *data = conn->data;
- struct HTTP *stream = conn->data->req.protop;
+ struct HTTP *stream = conn->data->req.p.http;
result = Curl_http2_setup(conn);
if(result)
@@ -2299,7 +2269,7 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
data into stream->mem, overwriting data already there. */
if(H2_BUFSIZE < nread) {
failf(data, "connection buffer size is too small to store data following "
- "HTTP Upgrade response header: buflen=%zu, datalen=%zu",
+ "HTTP Upgrade response header: buflen=%d, datalen=%zu",
H2_BUFSIZE, nread);
return CURLE_HTTP2;
}
@@ -2310,41 +2280,13 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
if(nread)
memcpy(httpc->inbuf, mem, nread);
- httpc->inbuflen = nread;
-
- nproc = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)httpc->inbuf,
- httpc->inbuflen);
-
- if(nghttp2_is_fatal((int)nproc)) {
- failf(data, "nghttp2_session_mem_recv() failed: %s(%d)",
- nghttp2_strerror((int)nproc), (int)nproc);
- return CURLE_HTTP2;
- }
-
- H2BUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", nproc));
-
- if((ssize_t)nread == nproc) {
- httpc->inbuflen = 0;
- httpc->nread_inbuf = 0;
- }
- else {
- httpc->nread_inbuf += nproc;
- }
- /* Try to send some frames since we may read SETTINGS already. */
- rv = h2_session_send(data, httpc->h2);
+ httpc->inbuflen = nread;
- if(rv != 0) {
- failf(data, "nghttp2_session_send() failed: %s(%d)",
- nghttp2_strerror(rv), rv);
- return CURLE_HTTP2;
- }
+ DEBUGASSERT(httpc->nread_inbuf == 0);
- if(should_close_session(httpc)) {
- H2BUGF(infof(data,
- "nghttp2_session_send(): nothing to do in this session\n"));
+ if(-1 == h2_process_pending_input(conn, httpc, &result))
return CURLE_HTTP2;
- }
return CURLE_OK;
}
@@ -2358,7 +2300,7 @@ CURLcode Curl_http2_stream_pause(struct Curl_easy *data, bool pause)
return CURLE_OK;
#ifdef NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE
else {
- struct HTTP *stream = data->req.protop;
+ struct HTTP *stream = data->req.p.http;
struct http_conn *httpc = &data->conn->proto.httpc;
uint32_t window = !pause * HTTP2_HUGE_WINDOW_SIZE;
int rv = nghttp2_session_set_local_window_size(httpc->h2,
diff --git a/lib/http2.h b/lib/http2.h
index e82b21280..43a6863ab 100644
--- a/lib/http2.h
+++ b/lib/http2.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/http_chunks.c b/lib/http_chunks.c
index 767f806c8..498481475 100644
--- a/lib/http_chunks.c
+++ b/lib/http_chunks.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/http_chunks.h b/lib/http_chunks.h
index 8f4a33c8e..c8f072a2d 100644
--- a/lib/http_chunks.h
+++ b/lib/http_chunks.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/http_digest.c b/lib/http_digest.c
index b06dc0d82..dfa40dcb6 100644
--- a/lib/http_digest.c
+++ b/lib/http_digest.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/http_digest.h b/lib/http_digest.h
index 96e39a7dc..f7001edec 100644
--- a/lib/http_digest.h
+++ b/lib/http_digest.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c
index 0a19ec2af..872d172fc 100644
--- a/lib/http_negotiate.c
+++ b/lib/http_negotiate.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/http_negotiate.h b/lib/http_negotiate.h
index a737f6f78..cf1d007dc 100644
--- a/lib/http_negotiate.h
+++ b/lib/http_negotiate.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/http_ntlm.c b/lib/http_ntlm.c
index cab543c75..91e1d1f71 100644
--- a/lib/http_ntlm.c
+++ b/lib/http_ntlm.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/http_ntlm.h b/lib/http_ntlm.h
index 3ebdf979e..5ddf53872 100644
--- a/lib/http_ntlm.h
+++ b/lib/http_ntlm.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/http_proxy.c b/lib/http_proxy.c
index 76c6ecbbb..76f938a0c 100644
--- a/lib/http_proxy.c
+++ b/lib/http_proxy.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -102,9 +102,9 @@ CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex)
* This function might be called several times in the multi interface case
* if the proxy's CONNECT response is not instant.
*/
- prot_save = conn->data->req.protop;
+ prot_save = conn->data->req.p.http;
memset(&http_proxy, 0, sizeof(http_proxy));
- conn->data->req.protop = &http_proxy;
+ conn->data->req.p.http = &http_proxy;
connkeep(conn, "HTTP proxy CONNECT");
/* for the secondary socket (FTP), use the "connect to host"
@@ -125,7 +125,7 @@ CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex)
else
remote_port = conn->remote_port;
result = Curl_proxyCONNECT(conn, sockindex, hostname, remote_port);
- conn->data->req.protop = prot_save;
+ conn->data->req.p.http = prot_save;
if(CURLE_OK != result)
return result;
Curl_safefree(data->state.aptr.proxyuserpwd);
@@ -167,7 +167,7 @@ static CURLcode connect_init(struct connectdata *conn, bool reinit)
Curl_dyn_reset(&s->rcvbuf);
}
s->tunnel_state = TUNNEL_INIT;
- s->keepon = TRUE;
+ s->keepon = KEEPON_CONNECT;
s->cl = 0;
s->close_connection = FALSE;
return CURLE_OK;
@@ -339,7 +339,7 @@ static CURLcode CONNECT(struct connectdata *conn,
return CURLE_ABORTED_BY_CALLBACK;
if(result) {
- s->keepon = FALSE;
+ s->keepon = KEEPON_DONE;
break;
}
else if(gotbytes <= 0) {
@@ -353,11 +353,11 @@ static CURLcode CONNECT(struct connectdata *conn,
error = SELECT_ERROR;
failf(data, "Proxy CONNECT aborted");
}
- s->keepon = FALSE;
+ s->keepon = KEEPON_DONE;
break;
}
- if(s->keepon > TRUE) {
+ if(s->keepon == KEEPON_IGNORE) {
/* This means we are currently ignoring a response-body */
if(s->cl) {
@@ -365,7 +365,7 @@ static CURLcode CONNECT(struct connectdata *conn,
and make sure to break out of the loop when we're done! */
s->cl--;
if(s->cl <= 0) {
- s->keepon = FALSE;
+ s->keepon = KEEPON_DONE;
s->tunnel_state = TUNNEL_COMPLETE;
break;
}
@@ -383,7 +383,7 @@ static CURLcode CONNECT(struct connectdata *conn,
if(r == CHUNKE_STOP) {
/* we're done reading chunks! */
infof(data, "chunk reading DONE\n");
- s->keepon = FALSE;
+ s->keepon = KEEPON_DONE;
/* we did the full CONNECT treatment, go COMPLETE */
s->tunnel_state = TUNNEL_COMPLETE;
}
@@ -410,8 +410,7 @@ static CURLcode CONNECT(struct connectdata *conn,
return result;
/* output debug if that is requested */
- if(data->set.verbose)
- Curl_debug(data, CURLINFO_HEADER_IN, linep, perline);
+ Curl_debug(data, CURLINFO_HEADER_IN, linep, perline);
if(!data->set.suppress_connect_headers) {
/* send the header to the callback */
@@ -425,7 +424,6 @@ static CURLcode CONNECT(struct connectdata *conn,
}
data->info.header_size += (long)perline;
- data->req.headerbytecount += (long)perline;
/* Newlines are CRLF, so the CR is ignored as the line isn't
really terminated until the LF comes. Treat a following CR
@@ -439,7 +437,7 @@ static CURLcode CONNECT(struct connectdata *conn,
/* If we get a 407 response code with content length
when we have no auth problem, we must ignore the
whole response-body */
- s->keepon = 2;
+ s->keepon = KEEPON_IGNORE;
if(s->cl) {
infof(data, "Ignore %" CURL_FORMAT_CURL_OFF_T
@@ -467,7 +465,7 @@ static CURLcode CONNECT(struct connectdata *conn,
if(r == CHUNKE_STOP) {
/* we're done reading chunks! */
infof(data, "chunk reading DONE\n");
- s->keepon = FALSE;
+ s->keepon = KEEPON_DONE;
/* we did the full CONNECT treatment, go to COMPLETE */
s->tunnel_state = TUNNEL_COMPLETE;
}
@@ -476,11 +474,11 @@ static CURLcode CONNECT(struct connectdata *conn,
/* without content-length or chunked encoding, we
can't keep the connection alive since the close is
the end signal so we bail out at once instead */
- s->keepon = FALSE;
+ s->keepon = KEEPON_DONE;
}
}
else
- s->keepon = FALSE;
+ s->keepon = KEEPON_DONE;
if(!s->cl)
/* we did the full CONNECT treatment, go to COMPLETE */
s->tunnel_state = TUNNEL_COMPLETE;
diff --git a/lib/http_proxy.h b/lib/http_proxy.h
index 29988a696..a595e8b55 100644
--- a/lib/http_proxy.h
+++ b/lib/http_proxy.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/idn_win32.c b/lib/idn_win32.c
index 2f5850dd0..1d475a4ef 100644
--- a/lib/idn_win32.c
+++ b/lib/idn_win32.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/if2ip.c b/lib/if2ip.c
index 39388692e..21e00b1f1 100644
--- a/lib/if2ip.c
+++ b/lib/if2ip.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/if2ip.h b/lib/if2ip.h
index f193d4257..e074e476d 100644
--- a/lib/if2ip.h
+++ b/lib/if2ip.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/imap.c b/lib/imap.c
index ce8e1f259..149433740 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -132,6 +132,7 @@ const struct Curl_handler Curl_handler_imap = {
ZERO_NULL, /* connection_check */
PORT_IMAP, /* defport */
CURLPROTO_IMAP, /* protocol */
+ CURLPROTO_IMAP, /* family */
PROTOPT_CLOSEACTION| /* flags */
PROTOPT_URLOPTIONS
};
@@ -159,6 +160,7 @@ const struct Curl_handler Curl_handler_imaps = {
ZERO_NULL, /* connection_check */
PORT_IMAPS, /* defport */
CURLPROTO_IMAPS, /* protocol */
+ CURLPROTO_IMAP, /* family */
PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */
PROTOPT_URLOPTIONS
};
@@ -244,7 +246,7 @@ static bool imap_matchresp(const char *line, size_t len, const char *cmd)
static bool imap_endofresp(struct connectdata *conn, char *line, size_t len,
int *resp)
{
- struct IMAP *imap = conn->data->req.protop;
+ struct IMAP *imap = conn->data->req.p.imap;
struct imap_conn *imapc = &conn->proto.imapc;
const char *id = imapc->resptag;
size_t id_len = strlen(id);
@@ -605,7 +607,7 @@ static CURLcode imap_perform_list(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct IMAP *imap = data->req.protop;
+ struct IMAP *imap = data->req.p.imap;
if(imap->custom)
/* Send the custom request */
@@ -640,7 +642,7 @@ static CURLcode imap_perform_select(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct IMAP *imap = data->req.protop;
+ struct IMAP *imap = data->req.p.imap;
struct imap_conn *imapc = &conn->proto.imapc;
char *mailbox;
@@ -679,7 +681,7 @@ static CURLcode imap_perform_select(struct connectdata *conn)
static CURLcode imap_perform_fetch(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
- struct IMAP *imap = conn->data->req.protop;
+ struct IMAP *imap = conn->data->req.p.imap;
/* Check we have a UID */
if(imap->uid) {
@@ -727,7 +729,7 @@ static CURLcode imap_perform_append(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct IMAP *imap = data->req.protop;
+ struct IMAP *imap = data->req.p.imap;
char *mailbox;
/* Check we have a mailbox */
@@ -797,7 +799,7 @@ static CURLcode imap_perform_append(struct connectdata *conn)
static CURLcode imap_perform_search(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
- struct IMAP *imap = conn->data->req.protop;
+ struct IMAP *imap = conn->data->req.p.imap;
/* Check we have a query string */
if(!imap->query) {
@@ -1051,7 +1053,7 @@ static CURLcode imap_state_select_resp(struct connectdata *conn, int imapcode,
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct IMAP *imap = conn->data->req.protop;
+ struct IMAP *imap = conn->data->req.p.imap;
struct imap_conn *imapc = &conn->proto.imapc;
const char *line = data->state.buffer;
@@ -1176,6 +1178,9 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
else {
/* IMAP download */
data->req.maxdownload = size;
+ /* force a recv/send check of this connection, as the data might've been
+ read off the socket already */
+ data->conn->cselect_bits = CURL_CSELECT_IN;
Curl_setup_transfer(data, FIRSTSOCKET, size, FALSE, -1);
}
}
@@ -1380,7 +1385,7 @@ static CURLcode imap_init(struct connectdata *conn)
struct Curl_easy *data = conn->data;
struct IMAP *imap;
- imap = data->req.protop = calloc(sizeof(struct IMAP), 1);
+ imap = data->req.p.imap = calloc(sizeof(struct IMAP), 1);
if(!imap)
result = CURLE_OUT_OF_MEMORY;
@@ -1424,7 +1429,9 @@ static CURLcode imap_connect(struct connectdata *conn, bool *done)
imapc->preftype = IMAP_TYPE_ANY;
Curl_sasl_init(&imapc->sasl, &saslimap);
+ Curl_dyn_init(&imapc->dyn, DYN_IMAP_CMD);
/* Initialise the pingpong layer */
+ Curl_pp_setup(pp);
Curl_pp_init(pp);
/* Parse the URL options */
@@ -1457,7 +1464,7 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status,
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct IMAP *imap = data->req.protop;
+ struct IMAP *imap = data->req.p.imap;
(void)premature;
@@ -1517,7 +1524,7 @@ static CURLcode imap_perform(struct connectdata *conn, bool *connected,
/* This is IMAP and no proxy */
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct IMAP *imap = data->req.protop;
+ struct IMAP *imap = data->req.p.imap;
struct imap_conn *imapc = &conn->proto.imapc;
bool selected = FALSE;
@@ -1626,6 +1633,7 @@ static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection)
/* Disconnect from the server */
Curl_pp_disconnect(&imapc->pp);
+ Curl_dyn_free(&imapc->dyn);
/* Cleanup the SASL module */
Curl_sasl_cleanup(conn, imapc->sasl.authused);
@@ -1640,7 +1648,7 @@ static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection)
/* Call this when the DO phase has completed */
static CURLcode imap_dophase_done(struct connectdata *conn, bool connected)
{
- struct IMAP *imap = conn->data->req.protop;
+ struct IMAP *imap = conn->data->req.p.imap;
(void)connected;
@@ -1727,30 +1735,25 @@ static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...)
{
CURLcode result = CURLE_OK;
struct imap_conn *imapc = &conn->proto.imapc;
- char *taggedfmt;
- va_list ap;
DEBUGASSERT(fmt);
- /* Calculate the next command ID wrapping at 3 digits */
- imapc->cmdid = (imapc->cmdid + 1) % 1000;
-
/* Calculate the tag based on the connection ID and command ID */
msnprintf(imapc->resptag, sizeof(imapc->resptag), "%c%03d",
- 'A' + curlx_sltosi(conn->connection_id % 26), imapc->cmdid);
-
- /* Prefix the format with the tag */
- taggedfmt = aprintf("%s %s", imapc->resptag, fmt);
- if(!taggedfmt)
- return CURLE_OUT_OF_MEMORY;
+ 'A' + curlx_sltosi(conn->connection_id % 26),
+ (++imapc->cmdid)%1000);
- /* Send the data with the tag */
- va_start(ap, fmt);
- result = Curl_pp_vsendf(&imapc->pp, taggedfmt, ap);
- va_end(ap);
-
- free(taggedfmt);
+ /* start with a blank buffer */
+ Curl_dyn_reset(&imapc->dyn);
+ /* append tag + space + fmt */
+ result = Curl_dyn_addf(&imapc->dyn, "%s %s", imapc->resptag, fmt);
+ if(!result) {
+ va_list ap;
+ va_start(ap, fmt);
+ result = Curl_pp_vsendf(&imapc->pp, Curl_dyn_ptr(&imapc->dyn), ap);
+ va_end(ap);
+ }
return result;
}
@@ -1942,7 +1945,7 @@ static CURLcode imap_parse_url_path(struct connectdata *conn)
/* The imap struct is already initialised in imap_connect() */
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct IMAP *imap = data->req.protop;
+ struct IMAP *imap = data->req.p.imap;
const char *begin = &data->state.up.path[1]; /* skip leading slash */
const char *ptr = begin;
@@ -2074,7 +2077,7 @@ static CURLcode imap_parse_custom_request(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct IMAP *imap = data->req.protop;
+ struct IMAP *imap = data->req.p.imap;
const char *custom = data->set.str[STRING_CUSTOMREQUEST];
if(custom) {
diff --git a/lib/imap.h b/lib/imap.h
index 4786f5624..ef6515d8c 100644
--- a/lib/imap.h
+++ b/lib/imap.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2009 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2009 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -75,13 +75,14 @@ struct imap_conn {
bool preauth; /* Is this connection PREAUTH? */
struct SASL sasl; /* SASL-related parameters */
unsigned int preftype; /* Preferred authentication type */
- int cmdid; /* Last used command ID */
+ unsigned int cmdid; /* Last used command ID */
char resptag[5]; /* Response tag to wait for */
bool tls_supported; /* StartTLS capability supported by server */
bool login_disabled; /* LOGIN command disabled by server */
bool ir_supported; /* Initial response supported by server */
char *mailbox; /* The last selected mailbox */
char *mailbox_uidvalidity; /* UIDVALIDITY parsed from select response */
+ struct dynbuf dyn; /* for the IMAP commands */
};
extern const struct Curl_handler Curl_handler_imap;
diff --git a/lib/inet_ntop.h b/lib/inet_ntop.h
index 9d3f237f3..067632aae 100644
--- a/lib/inet_ntop.h
+++ b/lib/inet_ntop.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/inet_pton.c b/lib/inet_pton.c
index 9c87a0562..4923cae24 100644
--- a/lib/inet_pton.c
+++ b/lib/inet_pton.c
@@ -1,6 +1,6 @@
/* This is from the BIND 4.9.4 release, modified to compile by itself */
-/* Copyright (c) 1996 - 2019 by Internet Software Consortium.
+/* Copyright (c) 1996 - 2020 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -112,7 +112,7 @@ inet_pton4(const char *src, unsigned char *dst)
if(val > 255)
return (0);
*tp = (unsigned char)val;
- if(! saw_digit) {
+ if(!saw_digit) {
if(++octets > 4)
return (0);
saw_digit = 1;
diff --git a/lib/inet_pton.h b/lib/inet_pton.h
index e695af9c6..ec1237309 100644
--- a/lib/inet_pton.h
+++ b/lib/inet_pton.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/krb5.c b/lib/krb5.c
index f50287aec..66394f4f3 100644
--- a/lib/krb5.c
+++ b/lib/krb5.c
@@ -2,7 +2,7 @@
*
* Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
- * Copyright (c) 2004 - 2019 Daniel Stenberg
+ * Copyright (c) 2004 - 2020 Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -45,14 +45,73 @@
#include "ftp.h"
#include "curl_gssapi.h"
#include "sendf.h"
-#include "curl_sec.h"
+#include "curl_krb5.h"
#include "warnless.h"
+#include "non-ascii.h"
+#include "strcase.h"
+#include "strdup.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
#include "memdebug.h"
+static CURLcode ftpsend(struct connectdata *conn, const char *cmd)
+{
+ ssize_t bytes_written;
+#define SBUF_SIZE 1024
+ char s[SBUF_SIZE];
+ size_t write_len;
+ char *sptr = s;
+ CURLcode result = CURLE_OK;
+#ifdef HAVE_GSSAPI
+ enum protection_level data_sec = conn->data_prot;
+#endif
+
+ if(!cmd)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+
+ write_len = strlen(cmd);
+ if(!write_len || write_len > (sizeof(s) -3))
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+
+ memcpy(&s, cmd, write_len);
+ strcpy(&s[write_len], "\r\n"); /* append a trailing CRLF */
+ write_len += 2;
+ bytes_written = 0;
+
+ result = Curl_convert_to_network(conn->data, s, write_len);
+ /* Curl_convert_to_network calls failf if unsuccessful */
+ if(result)
+ return result;
+
+ for(;;) {
+#ifdef HAVE_GSSAPI
+ conn->data_prot = PROT_CMD;
+#endif
+ result = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len,
+ &bytes_written);
+#ifdef HAVE_GSSAPI
+ DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST);
+ conn->data_prot = data_sec;
+#endif
+
+ if(result)
+ break;
+
+ Curl_debug(conn->data, CURLINFO_HEADER_OUT, sptr, (size_t)bytes_written);
+
+ if(bytes_written != (ssize_t)write_len) {
+ write_len -= bytes_written;
+ sptr += bytes_written;
+ }
+ else
+ break;
+ }
+
+ return result;
+}
+
static int
krb5_init(void *app_data)
{
@@ -183,7 +242,7 @@ krb5_auth(void *app_data, struct connectdata *conn)
for(;;) {
/* this really shouldn't be repeated here, but can't help it */
if(service == srv_host) {
- result = Curl_ftpsend(conn, "AUTH GSSAPI");
+ result = ftpsend(conn, "AUTH GSSAPI");
if(result)
return -2;
@@ -260,7 +319,7 @@ krb5_auth(void *app_data, struct connectdata *conn)
cmd = aprintf("ADAT %s", p);
if(cmd)
- result = Curl_ftpsend(conn, cmd);
+ result = ftpsend(conn, cmd);
else
result = CURLE_OUT_OF_MEMORY;
@@ -326,16 +385,524 @@ static void krb5_end(void *app_data)
}
}
-struct Curl_sec_client_mech Curl_krb5_client_mech = {
- "GSSAPI",
- sizeof(gss_ctx_id_t),
- krb5_init,
- krb5_auth,
- krb5_end,
- krb5_check_prot,
- krb5_overhead,
- krb5_encode,
- krb5_decode
+static struct Curl_sec_client_mech Curl_krb5_client_mech = {
+ "GSSAPI",
+ sizeof(gss_ctx_id_t),
+ krb5_init,
+ krb5_auth,
+ krb5_end,
+ krb5_check_prot,
+ krb5_overhead,
+ krb5_encode,
+ krb5_decode
+};
+
+static const struct {
+ enum protection_level level;
+ const char *name;
+} level_names[] = {
+ { PROT_CLEAR, "clear" },
+ { PROT_SAFE, "safe" },
+ { PROT_CONFIDENTIAL, "confidential" },
+ { PROT_PRIVATE, "private" }
};
+static enum protection_level
+name_to_level(const char *name)
+{
+ int i;
+ for(i = 0; i < (int)sizeof(level_names)/(int)sizeof(level_names[0]); i++)
+ if(checkprefix(name, level_names[i].name))
+ return level_names[i].level;
+ return PROT_NONE;
+}
+
+/* Convert a protocol |level| to its char representation.
+ We take an int to catch programming mistakes. */
+static char level_to_char(int level)
+{
+ switch(level) {
+ case PROT_CLEAR:
+ return 'C';
+ case PROT_SAFE:
+ return 'S';
+ case PROT_CONFIDENTIAL:
+ return 'E';
+ case PROT_PRIVATE:
+ return 'P';
+ case PROT_CMD:
+ /* Fall through */
+ default:
+ /* Those 2 cases should not be reached! */
+ break;
+ }
+ DEBUGASSERT(0);
+ /* Default to the most secure alternative. */
+ return 'P';
+}
+
+/* Send an FTP command defined by |message| and the optional arguments. The
+ function returns the ftp_code. If an error occurs, -1 is returned. */
+static int ftp_send_command(struct connectdata *conn, const char *message, ...)
+{
+ int ftp_code;
+ ssize_t nread = 0;
+ va_list args;
+ char print_buffer[50];
+
+ va_start(args, message);
+ mvsnprintf(print_buffer, sizeof(print_buffer), message, args);
+ va_end(args);
+
+ if(ftpsend(conn, print_buffer)) {
+ ftp_code = -1;
+ }
+ else {
+ if(Curl_GetFTPResponse(&nread, conn, &ftp_code))
+ ftp_code = -1;
+ }
+
+ (void)nread; /* Unused */
+ return ftp_code;
+}
+
+/* Read |len| from the socket |fd| and store it in |to|. Return a CURLcode
+ saying whether an error occurred or CURLE_OK if |len| was read. */
+static CURLcode
+socket_read(curl_socket_t fd, void *to, size_t len)
+{
+ char *to_p = to;
+ CURLcode result;
+ ssize_t nread = 0;
+
+ while(len > 0) {
+ result = Curl_read_plain(fd, to_p, len, &nread);
+ if(!result) {
+ len -= nread;
+ to_p += nread;
+ }
+ else {
+ if(result == CURLE_AGAIN)
+ continue;
+ return result;
+ }
+ }
+ return CURLE_OK;
+}
+
+
+/* Write |len| bytes from the buffer |to| to the socket |fd|. Return a
+ CURLcode saying whether an error occurred or CURLE_OK if |len| was
+ written. */
+static CURLcode
+socket_write(struct connectdata *conn, curl_socket_t fd, const void *to,
+ size_t len)
+{
+ const char *to_p = to;
+ CURLcode result;
+ ssize_t written;
+
+ while(len > 0) {
+ result = Curl_write_plain(conn, fd, to_p, len, &written);
+ if(!result) {
+ len -= written;
+ to_p += written;
+ }
+ else {
+ if(result == CURLE_AGAIN)
+ continue;
+ return result;
+ }
+ }
+ return CURLE_OK;
+}
+
+static CURLcode read_data(struct connectdata *conn,
+ curl_socket_t fd,
+ struct krb5buffer *buf)
+{
+ int len;
+ CURLcode result;
+
+ result = socket_read(fd, &len, sizeof(len));
+ if(result)
+ return result;
+
+ if(len) {
+ /* only realloc if there was a length */
+ len = ntohl(len);
+ buf->data = Curl_saferealloc(buf->data, len);
+ }
+ if(!len || !buf->data)
+ return CURLE_OUT_OF_MEMORY;
+
+ result = socket_read(fd, buf->data, len);
+ if(result)
+ return result;
+ buf->size = conn->mech->decode(conn->app_data, buf->data, len,
+ conn->data_prot, conn);
+ buf->index = 0;
+ return CURLE_OK;
+}
+
+static size_t
+buffer_read(struct krb5buffer *buf, void *data, size_t len)
+{
+ if(buf->size - buf->index < len)
+ len = buf->size - buf->index;
+ memcpy(data, (char *)buf->data + buf->index, len);
+ buf->index += len;
+ return len;
+}
+
+/* Matches Curl_recv signature */
+static ssize_t sec_recv(struct connectdata *conn, int sockindex,
+ char *buffer, size_t len, CURLcode *err)
+{
+ size_t bytes_read;
+ size_t total_read = 0;
+ curl_socket_t fd = conn->sock[sockindex];
+
+ *err = CURLE_OK;
+
+ /* Handle clear text response. */
+ if(conn->sec_complete == 0 || conn->data_prot == PROT_CLEAR)
+ return sread(fd, buffer, len);
+
+ if(conn->in_buffer.eof_flag) {
+ conn->in_buffer.eof_flag = 0;
+ return 0;
+ }
+
+ bytes_read = buffer_read(&conn->in_buffer, buffer, len);
+ len -= bytes_read;
+ total_read += bytes_read;
+ buffer += bytes_read;
+
+ while(len > 0) {
+ if(read_data(conn, fd, &conn->in_buffer))
+ return -1;
+ if(conn->in_buffer.size == 0) {
+ if(bytes_read > 0)
+ conn->in_buffer.eof_flag = 1;
+ return bytes_read;
+ }
+ bytes_read = buffer_read(&conn->in_buffer, buffer, len);
+ len -= bytes_read;
+ total_read += bytes_read;
+ buffer += bytes_read;
+ }
+ return total_read;
+}
+
+/* Send |length| bytes from |from| to the |fd| socket taking care of encoding
+ and negotiating with the server. |from| can be NULL. */
+static void do_sec_send(struct connectdata *conn, curl_socket_t fd,
+ const char *from, int length)
+{
+ int bytes, htonl_bytes; /* 32-bit integers for htonl */
+ char *buffer = NULL;
+ char *cmd_buffer;
+ size_t cmd_size = 0;
+ CURLcode error;
+ enum protection_level prot_level = conn->data_prot;
+ bool iscmd = (prot_level == PROT_CMD)?TRUE:FALSE;
+
+ DEBUGASSERT(prot_level > PROT_NONE && prot_level < PROT_LAST);
+
+ if(iscmd) {
+ if(!strncmp(from, "PASS ", 5) || !strncmp(from, "ACCT ", 5))
+ prot_level = PROT_PRIVATE;
+ else
+ prot_level = conn->command_prot;
+ }
+ bytes = conn->mech->encode(conn->app_data, from, length, prot_level,
+ (void **)&buffer);
+ if(!buffer || bytes <= 0)
+ return; /* error */
+
+ if(iscmd) {
+ error = Curl_base64_encode(conn->data, buffer, curlx_sitouz(bytes),
+ &cmd_buffer, &cmd_size);
+ if(error) {
+ free(buffer);
+ return; /* error */
+ }
+ if(cmd_size > 0) {
+ static const char *enc = "ENC ";
+ static const char *mic = "MIC ";
+ if(prot_level == PROT_PRIVATE)
+ socket_write(conn, fd, enc, 4);
+ else
+ socket_write(conn, fd, mic, 4);
+
+ socket_write(conn, fd, cmd_buffer, cmd_size);
+ socket_write(conn, fd, "\r\n", 2);
+ infof(conn->data, "Send: %s%s\n", prot_level == PROT_PRIVATE?enc:mic,
+ cmd_buffer);
+ free(cmd_buffer);
+ }
+ }
+ else {
+ htonl_bytes = htonl(bytes);
+ socket_write(conn, fd, &htonl_bytes, sizeof(htonl_bytes));
+ socket_write(conn, fd, buffer, curlx_sitouz(bytes));
+ }
+ free(buffer);
+}
+
+static ssize_t sec_write(struct connectdata *conn, curl_socket_t fd,
+ const char *buffer, size_t length)
+{
+ ssize_t tx = 0, len = conn->buffer_size;
+
+ len -= conn->mech->overhead(conn->app_data, conn->data_prot,
+ curlx_sztosi(len));
+ if(len <= 0)
+ len = length;
+ while(length) {
+ if(length < (size_t)len)
+ len = length;
+
+ do_sec_send(conn, fd, buffer, curlx_sztosi(len));
+ length -= len;
+ buffer += len;
+ tx += len;
+ }
+ return tx;
+}
+
+/* Matches Curl_send signature */
+static ssize_t sec_send(struct connectdata *conn, int sockindex,
+ const void *buffer, size_t len, CURLcode *err)
+{
+ curl_socket_t fd = conn->sock[sockindex];
+ *err = CURLE_OK;
+ return sec_write(conn, fd, buffer, len);
+}
+
+int Curl_sec_read_msg(struct connectdata *conn, char *buffer,
+ enum protection_level level)
+{
+ /* decoded_len should be size_t or ssize_t but conn->mech->decode returns an
+ int */
+ int decoded_len;
+ char *buf;
+ int ret_code = 0;
+ size_t decoded_sz = 0;
+ CURLcode error;
+
+ if(!conn->mech)
+ /* not inititalized, return error */
+ return -1;
+
+ DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
+
+ error = Curl_base64_decode(buffer + 4, (unsigned char **)&buf, &decoded_sz);
+ if(error || decoded_sz == 0)
+ return -1;
+
+ if(decoded_sz > (size_t)INT_MAX) {
+ free(buf);
+ return -1;
+ }
+ decoded_len = curlx_uztosi(decoded_sz);
+
+ decoded_len = conn->mech->decode(conn->app_data, buf, decoded_len,
+ level, conn);
+ if(decoded_len <= 0) {
+ free(buf);
+ return -1;
+ }
+
+ {
+ buf[decoded_len] = '\n';
+ Curl_debug(conn->data, CURLINFO_HEADER_IN, buf, decoded_len + 1);
+ }
+
+ buf[decoded_len] = '\0';
+ if(decoded_len <= 3)
+ /* suspiciously short */
+ return 0;
+
+ if(buf[3] != '-')
+ /* safe to ignore return code */
+ (void)sscanf(buf, "%d", &ret_code);
+
+ if(buf[decoded_len - 1] == '\n')
+ buf[decoded_len - 1] = '\0';
+ strcpy(buffer, buf);
+ free(buf);
+ return ret_code;
+}
+
+static int sec_set_protection_level(struct connectdata *conn)
+{
+ int code;
+ enum protection_level level = conn->request_data_prot;
+
+ DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
+
+ if(!conn->sec_complete) {
+ infof(conn->data, "Trying to change the protection level after the"
+ " completion of the data exchange.\n");
+ return -1;
+ }
+
+ /* Bail out if we try to set up the same level */
+ if(conn->data_prot == level)
+ return 0;
+
+ if(level) {
+ char *pbsz;
+ static unsigned int buffer_size = 1 << 20; /* 1048576 */
+
+ code = ftp_send_command(conn, "PBSZ %u", buffer_size);
+ if(code < 0)
+ return -1;
+
+ if(code/100 != 2) {
+ failf(conn->data, "Failed to set the protection's buffer size.");
+ return -1;
+ }
+ conn->buffer_size = buffer_size;
+
+ pbsz = strstr(conn->data->state.buffer, "PBSZ=");
+ if(pbsz) {
+ /* ignore return code, use default value if it fails */
+ (void)sscanf(pbsz, "PBSZ=%u", &buffer_size);
+ if(buffer_size < conn->buffer_size)
+ conn->buffer_size = buffer_size;
+ }
+ }
+
+ /* Now try to negiociate the protection level. */
+ code = ftp_send_command(conn, "PROT %c", level_to_char(level));
+
+ if(code < 0)
+ return -1;
+
+ if(code/100 != 2) {
+ failf(conn->data, "Failed to set the protection level.");
+ return -1;
+ }
+
+ conn->data_prot = level;
+ if(level == PROT_PRIVATE)
+ conn->command_prot = level;
+
+ return 0;
+}
+
+int
+Curl_sec_request_prot(struct connectdata *conn, const char *level)
+{
+ enum protection_level l = name_to_level(level);
+ if(l == PROT_NONE)
+ return -1;
+ DEBUGASSERT(l > PROT_NONE && l < PROT_LAST);
+ conn->request_data_prot = l;
+ return 0;
+}
+
+static CURLcode choose_mech(struct connectdata *conn)
+{
+ int ret;
+ struct Curl_easy *data = conn->data;
+ void *tmp_allocation;
+ const struct Curl_sec_client_mech *mech = &Curl_krb5_client_mech;
+
+ tmp_allocation = realloc(conn->app_data, mech->size);
+ if(tmp_allocation == NULL) {
+ failf(data, "Failed realloc of size %zu", mech->size);
+ mech = NULL;
+ return CURLE_OUT_OF_MEMORY;
+ }
+ conn->app_data = tmp_allocation;
+
+ if(mech->init) {
+ ret = mech->init(conn->app_data);
+ if(ret) {
+ infof(data, "Failed initialization for %s. Skipping it.\n",
+ mech->name);
+ return CURLE_FAILED_INIT;
+ }
+ }
+
+ infof(data, "Trying mechanism %s...\n", mech->name);
+ ret = ftp_send_command(conn, "AUTH %s", mech->name);
+ if(ret < 0)
+ return CURLE_COULDNT_CONNECT;
+
+ if(ret/100 != 3) {
+ switch(ret) {
+ case 504:
+ infof(data, "Mechanism %s is not supported by the server (server "
+ "returned ftp code: 504).\n", mech->name);
+ break;
+ case 534:
+ infof(data, "Mechanism %s was rejected by the server (server returned "
+ "ftp code: 534).\n", mech->name);
+ break;
+ default:
+ if(ret/100 == 5) {
+ infof(data, "server does not support the security extensions\n");
+ return CURLE_USE_SSL_FAILED;
+ }
+ break;
+ }
+ return CURLE_LOGIN_DENIED;
+ }
+
+ /* Authenticate */
+ ret = mech->auth(conn->app_data, conn);
+
+ if(ret != AUTH_CONTINUE) {
+ if(ret != AUTH_OK) {
+ /* Mechanism has dumped the error to stderr, don't error here. */
+ return CURLE_USE_SSL_FAILED;
+ }
+ DEBUGASSERT(ret == AUTH_OK);
+
+ conn->mech = mech;
+ conn->sec_complete = 1;
+ conn->recv[FIRSTSOCKET] = sec_recv;
+ conn->send[FIRSTSOCKET] = sec_send;
+ conn->recv[SECONDARYSOCKET] = sec_recv;
+ conn->send[SECONDARYSOCKET] = sec_send;
+ conn->command_prot = PROT_SAFE;
+ /* Set the requested protection level */
+ /* BLOCKING */
+ (void)sec_set_protection_level(conn);
+ }
+
+ return CURLE_OK;
+}
+
+CURLcode
+Curl_sec_login(struct connectdata *conn)
+{
+ return choose_mech(conn);
+}
+
+
+void
+Curl_sec_end(struct connectdata *conn)
+{
+ if(conn->mech != NULL && conn->mech->end)
+ conn->mech->end(conn->app_data);
+ free(conn->app_data);
+ conn->app_data = NULL;
+ if(conn->in_buffer.data) {
+ free(conn->in_buffer.data);
+ conn->in_buffer.data = NULL;
+ conn->in_buffer.size = 0;
+ conn->in_buffer.index = 0;
+ conn->in_buffer.eof_flag = 0;
+ }
+ conn->sec_complete = 0;
+ conn->data_prot = PROT_CLEAR;
+ conn->mech = NULL;
+}
+
#endif /* HAVE_GSSAPI && !CURL_DISABLE_FTP */
diff --git a/lib/ldap.c b/lib/ldap.c
index 401c7613e..11768a417 100644
--- a/lib/ldap.c
+++ b/lib/ldap.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -150,6 +150,7 @@ const struct Curl_handler Curl_handler_ldap = {
ZERO_NULL, /* connection_check */
PORT_LDAP, /* defport */
CURLPROTO_LDAP, /* protocol */
+ CURLPROTO_LDAP, /* family */
PROTOPT_NONE /* flags */
};
@@ -176,6 +177,7 @@ const struct Curl_handler Curl_handler_ldaps = {
ZERO_NULL, /* connection_check */
PORT_LDAPS, /* defport */
CURLPROTO_LDAPS, /* protocol */
+ CURLPROTO_LDAP, /* family */
PROTOPT_SSL /* flags */
};
#endif
@@ -257,6 +259,13 @@ static int ldap_win_bind(struct connectdata *conn, LDAP *server,
}
#endif /* #if defined(USE_WIN32_LDAP) */
+#if defined(USE_WIN32_LDAP)
+#define FREE_ON_WINLDAP(x) curlx_unicodefree(x)
+#else
+#define FREE_ON_WINLDAP(x)
+#endif
+
+
static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
{
CURLcode result = CURLE_OK;
@@ -463,9 +472,6 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
}
#ifdef USE_WIN32_LDAP
ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
-#endif
-
-#ifdef USE_WIN32_LDAP
rc = ldap_win_bind(conn, server, user, passwd);
#else
rc = ldap_simple_bind_s(server, user, passwd);
@@ -507,7 +513,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
#if defined(USE_WIN32_LDAP)
TCHAR *attribute;
#else
- char *attribute; /*! suspicious that this isn't 'const' */
+ char *attribute;
#endif
int i;
@@ -532,30 +538,22 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
if(result) {
-#if defined(USE_WIN32_LDAP)
- curlx_unicodefree(name);
-#endif
+ FREE_ON_WINLDAP(name);
ldap_memfree(dn);
-
goto quit;
}
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *) name,
name_len);
if(result) {
-#if defined(USE_WIN32_LDAP)
- curlx_unicodefree(name);
-#endif
+ FREE_ON_WINLDAP(name);
ldap_memfree(dn);
-
goto quit;
}
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
if(result) {
-#if defined(USE_WIN32_LDAP)
- curlx_unicodefree(name);
-#endif
+ FREE_ON_WINLDAP(name);
ldap_memfree(dn);
goto quit;
@@ -563,9 +561,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
dlsize += name_len + 5;
-#if defined(USE_WIN32_LDAP)
- curlx_unicodefree(name);
-#endif
+ FREE_ON_WINLDAP(name);
ldap_memfree(dn);
}
@@ -596,9 +592,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
if(result) {
ldap_value_free_len(vals);
-#if defined(USE_WIN32_LDAP)
- curlx_unicodefree(attr);
-#endif
+ FREE_ON_WINLDAP(attr);
ldap_memfree(attribute);
if(ber)
ber_free(ber, 0);
@@ -610,9 +604,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
(char *) attr, attr_len);
if(result) {
ldap_value_free_len(vals);
-#if defined(USE_WIN32_LDAP)
- curlx_unicodefree(attr);
-#endif
+ FREE_ON_WINLDAP(attr);
ldap_memfree(attribute);
if(ber)
ber_free(ber, 0);
@@ -623,9 +615,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
if(result) {
ldap_value_free_len(vals);
-#if defined(USE_WIN32_LDAP)
- curlx_unicodefree(attr);
-#endif
+ FREE_ON_WINLDAP(attr);
ldap_memfree(attribute);
if(ber)
ber_free(ber, 0);
@@ -645,9 +635,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
&val_b64_sz);
if(result) {
ldap_value_free_len(vals);
-#if defined(USE_WIN32_LDAP)
- curlx_unicodefree(attr);
-#endif
+ FREE_ON_WINLDAP(attr);
ldap_memfree(attribute);
if(ber)
ber_free(ber, 0);
@@ -661,9 +649,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
free(val_b64);
if(result) {
ldap_value_free_len(vals);
-#if defined(USE_WIN32_LDAP)
- curlx_unicodefree(attr);
-#endif
+ FREE_ON_WINLDAP(attr);
ldap_memfree(attribute);
if(ber)
ber_free(ber, 0);
@@ -679,9 +665,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
vals[i]->bv_len);
if(result) {
ldap_value_free_len(vals);
-#if defined(USE_WIN32_LDAP)
- curlx_unicodefree(attr);
-#endif
+ FREE_ON_WINLDAP(attr);
ldap_memfree(attribute);
if(ber)
ber_free(ber, 0);
@@ -695,9 +679,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
if(result) {
ldap_value_free_len(vals);
-#if defined(USE_WIN32_LDAP)
- curlx_unicodefree(attr);
-#endif
+ FREE_ON_WINLDAP(attr);
ldap_memfree(attribute);
if(ber)
ber_free(ber, 0);
@@ -713,9 +695,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
}
/* Free the attribute as we are done with it */
-#if defined(USE_WIN32_LDAP)
- curlx_unicodefree(attr);
-#endif
+ FREE_ON_WINLDAP(attr);
ldap_memfree(attribute);
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
@@ -745,9 +725,7 @@ quit:
ldapssl_client_deinit();
#endif /* HAVE_LDAP_SSL && CURL_HAS_NOVELL_LDAPSDK */
-#if defined(USE_WIN32_LDAP)
- curlx_unicodefree(host);
-#endif
+ FREE_ON_WINLDAP(host);
/* no data to transfer */
Curl_setup_transfer(data, -1, -1, FALSE, -1);
@@ -945,7 +923,7 @@ static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp)
char *unescaped;
CURLcode result;
- LDAP_TRACE(("attr[%d] '%s'\n", i, attributes[i]));
+ LDAP_TRACE(("attr[%zu] '%s'\n", i, attributes[i]));
/* Unescape the attribute */
result = Curl_urldecode(conn->data, attributes[i], 0, &unescaped, NULL,
diff --git a/lib/libcurl.rc b/lib/libcurl.rc
index 97f490a25..80f8631e9 100644
--- a/lib/libcurl.rc
+++ b/lib/libcurl.rc
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -44,7 +44,7 @@ BEGIN
BEGIN
BLOCK "040904b0"
BEGIN
- VALUE "CompanyName", "The curl library, https://curl.haxx.se/\0"
+ VALUE "CompanyName", "The curl library, https://curl.se/\0"
VALUE "FileDescription", "libcurl Shared Library\0"
VALUE "FileVersion", LIBCURL_VERSION "\0"
VALUE "InternalName", "libcurl\0"
@@ -52,7 +52,7 @@ BEGIN
VALUE "ProductName", "The curl library\0"
VALUE "ProductVersion", LIBCURL_VERSION "\0"
VALUE "LegalCopyright", "\xa9 " LIBCURL_COPYRIGHT "\0" /* a9: Copyright symbol */
- VALUE "License", "https://curl.haxx.se/docs/copyright.html\0"
+ VALUE "License", "https://curl.se/docs/copyright.html\0"
END
END
diff --git a/lib/libgnurl.plist b/lib/libgnurl.plist
index 33c2fdefa..ae24a69ff 100644
--- a/lib/libgnurl.plist
+++ b/lib/libgnurl.plist
@@ -12,7 +12,7 @@
<string>gnurl</string>
<key>CFBundleIdentifier</key>
- <string>se.haxx.curl.libcurl</string>
+ <string>se.curl.libcurl</string>
<key>CFBundleVersion</key>
<string>7.12.3</string>
diff --git a/lib/llist.c b/lib/llist.c
index 694b0fbaf..b48f30665 100644
--- a/lib/llist.c
+++ b/lib/llist.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -34,7 +34,7 @@
* @unittest: 1300
*/
void
-Curl_llist_init(struct curl_llist *l, curl_llist_dtor dtor)
+Curl_llist_init(struct Curl_llist *l, Curl_llist_dtor dtor)
{
l->size = 0;
l->dtor = dtor;
@@ -54,9 +54,9 @@ Curl_llist_init(struct curl_llist *l, curl_llist_dtor dtor)
* @unittest: 1300
*/
void
-Curl_llist_insert_next(struct curl_llist *list, struct curl_llist_element *e,
+Curl_llist_insert_next(struct Curl_llist *list, struct Curl_llist_element *e,
const void *p,
- struct curl_llist_element *ne)
+ struct Curl_llist_element *ne)
{
ne->ptr = (void *) p;
if(list->size == 0) {
@@ -90,7 +90,7 @@ Curl_llist_insert_next(struct curl_llist *list, struct curl_llist_element *e,
* @unittest: 1300
*/
void
-Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e,
+Curl_llist_remove(struct Curl_llist *list, struct Curl_llist_element *e,
void *user)
{
void *ptr;
@@ -131,7 +131,7 @@ Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e,
}
void
-Curl_llist_destroy(struct curl_llist *list, void *user)
+Curl_llist_destroy(struct Curl_llist *list, void *user)
{
if(list) {
while(list->size > 0)
@@ -140,7 +140,7 @@ Curl_llist_destroy(struct curl_llist *list, void *user)
}
size_t
-Curl_llist_count(struct curl_llist *list)
+Curl_llist_count(struct Curl_llist *list)
{
return list->size;
}
diff --git a/lib/llist.h b/lib/llist.h
index 0178c4259..ceae2dd1b 100644
--- a/lib/llist.h
+++ b/lib/llist.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -25,26 +25,26 @@
#include "curl_setup.h"
#include <stddef.h>
-typedef void (*curl_llist_dtor)(void *, void *);
+typedef void (*Curl_llist_dtor)(void *, void *);
-struct curl_llist_element {
+struct Curl_llist_element {
void *ptr;
- struct curl_llist_element *prev;
- struct curl_llist_element *next;
+ struct Curl_llist_element *prev;
+ struct Curl_llist_element *next;
};
-struct curl_llist {
- struct curl_llist_element *head;
- struct curl_llist_element *tail;
- curl_llist_dtor dtor;
+struct Curl_llist {
+ struct Curl_llist_element *head;
+ struct Curl_llist_element *tail;
+ Curl_llist_dtor dtor;
size_t size;
};
-void Curl_llist_init(struct curl_llist *, curl_llist_dtor);
-void Curl_llist_insert_next(struct curl_llist *, struct curl_llist_element *,
- const void *, struct curl_llist_element *node);
-void Curl_llist_remove(struct curl_llist *, struct curl_llist_element *,
+void Curl_llist_init(struct Curl_llist *, Curl_llist_dtor);
+void Curl_llist_insert_next(struct Curl_llist *, struct Curl_llist_element *,
+ const void *, struct Curl_llist_element *node);
+void Curl_llist_remove(struct Curl_llist *, struct Curl_llist_element *,
void *);
-size_t Curl_llist_count(struct curl_llist *);
-void Curl_llist_destroy(struct curl_llist *, void *);
+size_t Curl_llist_count(struct Curl_llist *);
+void Curl_llist_destroy(struct Curl_llist *, void *);
#endif /* HEADER_CURL_LLIST_H */
diff --git a/lib/makefile.amiga b/lib/makefile.amiga
index 29df65438..698a8f4de 100644
--- a/lib/makefile.amiga
+++ b/lib/makefile.amiga
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/lib/makefile.dj b/lib/makefile.dj
index 6ea79e4be..2b18ad6d5 100644
--- a/lib/makefile.dj
+++ b/lib/makefile.dj
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/lib/md4.c b/lib/md4.c
index 67119cda5..8ae6ac3fa 100644
--- a/lib/md4.c
+++ b/lib/md4.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/md5.c b/lib/md5.c
index dae303681..72703e8c6 100644
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/memdebug.c b/lib/memdebug.c
index f7ed88539..86e195e2f 100644
--- a/lib/memdebug.c
+++ b/lib/memdebug.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -35,52 +35,6 @@
#include "curl_memory.h"
#include "memdebug.h"
-/*
- * Until 2011-08-17 libcurl's Memory Tracking feature also performed
- * automatic malloc and free filling operations using 0xA5 and 0x13
- * values. Our own preinitialization of dynamically allocated memory
- * might be useful when not using third party memory debuggers, but
- * on the other hand this would fool memory debuggers into thinking
- * that all dynamically allocated memory is properly initialized.
- *
- * As a default setting, libcurl's Memory Tracking feature no longer
- * performs preinitialization of dynamically allocated memory on its
- * own. If you know what you are doing, and really want to retain old
- * behavior, you can achieve this compiling with preprocessor symbols
- * CURL_MT_MALLOC_FILL and CURL_MT_FREE_FILL defined with appropriate
- * values.
- */
-
-#ifdef CURL_MT_MALLOC_FILL
-# if (CURL_MT_MALLOC_FILL < 0) || (CURL_MT_MALLOC_FILL > 0xff)
-# error "invalid CURL_MT_MALLOC_FILL or out of range"
-# endif
-#endif
-
-#ifdef CURL_MT_FREE_FILL
-# if (CURL_MT_FREE_FILL < 0) || (CURL_MT_FREE_FILL > 0xff)
-# error "invalid CURL_MT_FREE_FILL or out of range"
-# endif
-#endif
-
-#if defined(CURL_MT_MALLOC_FILL) && defined(CURL_MT_FREE_FILL)
-# if (CURL_MT_MALLOC_FILL == CURL_MT_FREE_FILL)
-# error "CURL_MT_MALLOC_FILL same as CURL_MT_FREE_FILL"
-# endif
-#endif
-
-#ifdef CURL_MT_MALLOC_FILL
-# define mt_malloc_fill(buf,len) memset((buf), CURL_MT_MALLOC_FILL, (len))
-#else
-# define mt_malloc_fill(buf,len) Curl_nop_stmt
-#endif
-
-#ifdef CURL_MT_FREE_FILL
-# define mt_free_fill(buf,len) memset((buf), CURL_MT_FREE_FILL, (len))
-#else
-# define mt_free_fill(buf,len) Curl_nop_stmt
-#endif
-
struct memdebug {
size_t size;
union {
@@ -173,8 +127,6 @@ void *curl_dbg_malloc(size_t wantedsize, int line, const char *source)
mem = (Curl_cmalloc)(size);
if(mem) {
- /* fill memory with junk */
- mt_malloc_fill(mem->mem, wantedsize);
mem->size = wantedsize;
}
@@ -321,9 +273,6 @@ void curl_dbg_free(void *ptr, int line, const char *source)
# pragma warning(pop)
#endif
- /* destroy */
- mt_free_fill(mem->mem, mem->size);
-
/* free for real */
(Curl_cfree)(mem);
}
diff --git a/lib/memdebug.h b/lib/memdebug.h
index 4edafdfb5..8e88cea58 100644
--- a/lib/memdebug.h
+++ b/lib/memdebug.h
@@ -12,7 +12,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/mime.c b/lib/mime.c
index 88448edc6..128cbe22c 100644
--- a/lib/mime.c
+++ b/lib/mime.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/mime.h b/lib/mime.h
index 50b7ea6b0..ab89d5251 100644
--- a/lib/mime.h
+++ b/lib/mime.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/mk-ca-bundle.pl b/lib/mk-ca-bundle.pl
index b9c7ed257..5ed53fe0d 100755
--- a/lib/mk-ca-bundle.pl
+++ b/lib/mk-ca-bundle.pl
@@ -10,7 +10,7 @@
# *
# * This software is licensed as described in the file COPYING, which
# * you should have received as part of this distribution. The terms
-# * are also available at https://curl.haxx.se/docs/copyright.html.
+# * are also available at https://curl.se/docs/copyright.html.
# *
# * You may opt to use, copy, modify, merge, publish, distribute and/or sell
# * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/mk-ca-bundle.vbs b/lib/mk-ca-bundle.vbs
index 34871711d..21b4c1967 100755
--- a/lib/mk-ca-bundle.vbs
+++ b/lib/mk-ca-bundle.vbs
@@ -9,7 +9,7 @@
'*
'* This software is licensed as described in the file COPYING, which
'* you should have received as part of this distribution. The terms
-'* are also available at https://curl.haxx.se/docs/copyright.html.
+'* are also available at https://curl.se/docs/copyright.html.
'*
'* You may opt to use, copy, modify, merge, publish, distribute and/or sell
'* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/mprintf.c b/lib/mprintf.c
index 1989bc084..972d0364a 100644
--- a/lib/mprintf.c
+++ b/lib/mprintf.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -99,12 +99,12 @@ static const char lower_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
/* Upper-case digits. */
static const char upper_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-#define OUTCHAR(x) \
- do{ \
+#define OUTCHAR(x) \
+ do { \
if(stream((unsigned char)(x), (FILE *)data) != -1) \
- done++; \
- else \
- return done; /* return immediately on failure */ \
+ done++; \
+ else \
+ return done; /* return immediately on failure */ \
} while(0)
/* Data type to read from the arglist */
@@ -169,7 +169,7 @@ struct nsprintf {
};
struct asprintf {
- struct dynbuf b;
+ struct dynbuf *b;
bool fail; /* if an alloc has failed and thus the output is not the complete
data */
};
@@ -878,7 +878,7 @@ static int dprintf_formatf(
OUTCHAR(' ');
for(point = strnil; *point != '\0'; ++point)
OUTCHAR(*point);
- if(! (p->flags & FLAGS_LEFT))
+ if(!(p->flags & FLAGS_LEFT))
while(width-- > 0)
OUTCHAR(' ');
}
@@ -1042,50 +1042,61 @@ static int alloc_addbyter(int output, FILE *data)
struct asprintf *infop = (struct asprintf *)data;
unsigned char outc = (unsigned char)output;
- if(Curl_dyn_addn(&infop->b, &outc, 1)) {
+ if(Curl_dyn_addn(infop->b, &outc, 1)) {
infop->fail = 1;
return -1; /* fail */
}
return outc; /* fputc() returns like this on success */
}
-char *curl_maprintf(const char *format, ...)
+extern int Curl_dyn_vprintf(struct dynbuf *dyn,
+ const char *format, va_list ap_save);
+
+/* appends the formatted string, returns 0 on success, 1 on error */
+int Curl_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list ap_save)
{
- va_list ap_save; /* argument pointer */
int retcode;
struct asprintf info;
- Curl_dyn_init(&info.b, DYN_APRINTF);
+ info.b = dyn;
info.fail = 0;
- va_start(ap_save, format);
retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
- va_end(ap_save);
if((-1 == retcode) || info.fail) {
- Curl_dyn_free(&info.b);
- return NULL;
+ Curl_dyn_free(info.b);
+ return 1;
}
- if(Curl_dyn_len(&info.b))
- return Curl_dyn_ptr(&info.b);
- return strdup("");
+ return 0;
}
char *curl_mvaprintf(const char *format, va_list ap_save)
{
int retcode;
struct asprintf info;
- Curl_dyn_init(&info.b, DYN_APRINTF);
+ struct dynbuf dyn;
+ info.b = &dyn;
+ Curl_dyn_init(info.b, DYN_APRINTF);
info.fail = 0;
retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
if((-1 == retcode) || info.fail) {
- Curl_dyn_free(&info.b);
+ Curl_dyn_free(info.b);
return NULL;
}
- if(Curl_dyn_len(&info.b))
- return Curl_dyn_ptr(&info.b);
+ if(Curl_dyn_len(info.b))
+ return Curl_dyn_ptr(info.b);
return strdup("");
}
+char *curl_maprintf(const char *format, ...)
+{
+ va_list ap_save;
+ char *s;
+ va_start(ap_save, format);
+ s = curl_mvaprintf(format, ap_save);
+ va_end(ap_save);
+ return s;
+}
+
static int storebuffer(int output, FILE *data)
{
char **buffer = (char **)data;
diff --git a/lib/mqtt.c b/lib/mqtt.c
index 0baffe2a7..dfcb04c88 100644
--- a/lib/mqtt.c
+++ b/lib/mqtt.c
@@ -10,7 +10,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -23,7 +23,7 @@
#include "curl_setup.h"
-#ifdef CURL_ENABLE_MQTT
+#ifndef CURL_DISABLE_MQTT
#include "urldata.h"
#include <gnurl/curl.h>
@@ -86,6 +86,7 @@ const struct Curl_handler Curl_handler_mqtt = {
ZERO_NULL, /* connection_check */
PORT_MQTT, /* defport */
CURLPROTO_MQTT, /* protocol */
+ CURLPROTO_MQTT, /* family */
PROTOPT_NONE /* flags */
};
@@ -95,12 +96,12 @@ static CURLcode mqtt_setup_conn(struct connectdata *conn)
during this request */
struct MQTT *mq;
struct Curl_easy *data = conn->data;
- DEBUGASSERT(data->req.protop == NULL);
+ DEBUGASSERT(data->req.p.mqtt == NULL);
mq = calloc(1, sizeof(struct MQTT));
if(!mq)
return CURLE_OUT_OF_MEMORY;
- data->req.protop = mq;
+ data->req.p.mqtt = mq;
return CURLE_OK;
}
@@ -110,10 +111,10 @@ static CURLcode mqtt_send(struct connectdata *conn,
CURLcode result = CURLE_OK;
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
struct Curl_easy *data = conn->data;
- struct MQTT *mq = data->req.protop;
+ struct MQTT *mq = data->req.p.mqtt;
ssize_t n;
result = Curl_write(conn, sockfd, buf, len, &n);
- if(!result && data->set.verbose)
+ if(!result)
Curl_debug(data, CURLINFO_HEADER_OUT, buf, (size_t)n);
if(len != (size_t)n) {
size_t nsend = len - n;
@@ -142,7 +143,7 @@ static CURLcode mqtt_connect(struct connectdata *conn)
const size_t client_id_offset = 14;
const size_t packetlen = client_id_offset + MQTT_CLIENTID_LEN;
char client_id[MQTT_CLIENTID_LEN + 1] = "curl";
- const size_t curl_len = strlen("curl");
+ const size_t clen = strlen("curl");
char packet[32] = {
MQTT_MSG_CONNECT, /* packet type */
0x00, /* remaining length */
@@ -156,8 +157,8 @@ static CURLcode mqtt_connect(struct connectdata *conn)
packet[1] = (packetlen - 2) & 0x7f;
packet[client_id_offset - 1] = MQTT_CLIENTID_LEN;
- result = Curl_rand_hex(conn->data, (unsigned char *)&client_id[curl_len],
- MQTT_CLIENTID_LEN - curl_len + 1);
+ result = Curl_rand_hex(conn->data, (unsigned char *)&client_id[clen],
+ MQTT_CLIENTID_LEN - clen + 1);
memcpy(&packet[client_id_offset], client_id, MQTT_CLIENTID_LEN);
infof(conn->data, "Using client id '%s'\n", client_id);
if(!result)
@@ -184,8 +185,7 @@ static CURLcode mqtt_verify_connack(struct connectdata *conn)
if(result)
goto fail;
- if(data->set.verbose)
- Curl_debug(data, CURLINFO_HEADER_IN, (char *)readbuf, (size_t)nread);
+ Curl_debug(data, CURLINFO_HEADER_IN, (char *)readbuf, (size_t)nread);
/* fixme */
if(nread < MQTT_CONNACK_LEN) {
@@ -297,8 +297,7 @@ static CURLcode mqtt_verify_suback(struct connectdata *conn)
if(result)
goto fail;
- if(conn->data->set.verbose)
- Curl_debug(conn->data, CURLINFO_HEADER_IN, (char *)readbuf, (size_t)nread);
+ Curl_debug(conn->data, CURLINFO_HEADER_IN, (char *)readbuf, (size_t)nread);
/* fixme */
if(nread < MQTT_SUBACK_LEN) {
@@ -426,7 +425,7 @@ static CURLcode mqtt_read_publish(struct connectdata *conn,
unsigned char *pkt = (unsigned char *)data->state.buffer;
size_t remlen;
struct mqtt_conn *mqtt = &conn->proto.mqtt;
- struct MQTT *mq = data->req.protop;
+ struct MQTT *mq = data->req.p.mqtt;
unsigned char packet;
switch(mqtt->state) {
@@ -485,8 +484,7 @@ static CURLcode mqtt_read_publish(struct connectdata *conn,
result = CURLE_PARTIAL_FILE;
goto end;
}
- if(data->set.verbose)
- Curl_debug(data, CURLINFO_DATA_IN, (char *)pkt, (size_t)nread);
+ Curl_debug(data, CURLINFO_DATA_IN, (char *)pkt, (size_t)nread);
mq->npacket -= nread;
k->bytecount += nread;
@@ -533,7 +531,7 @@ static CURLcode mqtt_doing(struct connectdata *conn, bool *done)
CURLcode result = CURLE_OK;
struct mqtt_conn *mqtt = &conn->proto.mqtt;
struct Curl_easy *data = conn->data;
- struct MQTT *mq = data->req.protop;
+ struct MQTT *mq = data->req.p.mqtt;
ssize_t nread;
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
unsigned char *pkt = (unsigned char *)data->state.buffer;
@@ -557,8 +555,7 @@ static CURLcode mqtt_doing(struct connectdata *conn, bool *done)
result = Curl_read(conn, sockfd, (char *)&mq->firstbyte, 1, &nread);
if(result)
break;
- if(data->set.verbose)
- Curl_debug(data, CURLINFO_HEADER_IN, (char *)&mq->firstbyte, 1);
+ Curl_debug(data, CURLINFO_HEADER_IN, (char *)&mq->firstbyte, 1);
/* remember the first byte */
mq->npacket = 0;
mqstate(conn, MQTT_REMAINING_LENGTH, MQTT_NOSTATE);
@@ -568,8 +565,7 @@ static CURLcode mqtt_doing(struct connectdata *conn, bool *done)
result = Curl_read(conn, sockfd, (char *)&byte, 1, &nread);
if(result)
break;
- if(data->set.verbose)
- Curl_debug(data, CURLINFO_HEADER_IN, (char *)&byte, 1);
+ Curl_debug(data, CURLINFO_HEADER_IN, (char *)&byte, 1);
pkt[mq->npacket++] = byte;
} while((byte & 0x80) && (mq->npacket < 4));
if(result)
@@ -625,4 +621,4 @@ static CURLcode mqtt_doing(struct connectdata *conn, bool *done)
return result;
}
-#endif /* CURL_ENABLE_MQTT */
+#endif /* CURL_DISABLE_MQTT */
diff --git a/lib/mqtt.h b/lib/mqtt.h
index 37463d58a..fb52c7232 100644
--- a/lib/mqtt.h
+++ b/lib/mqtt.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -22,7 +22,7 @@
*
***************************************************************************/
-#ifdef CURL_ENABLE_MQTT
+#ifndef CURL_DISABLE_MQTT
extern const struct Curl_handler Curl_handler_mqtt;
#endif
diff --git a/lib/multi.c b/lib/multi.c
index 581168f62..26a5f272c 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -190,7 +190,7 @@ static void mstate(struct Curl_easy *data, CURLMstate state
*/
struct Curl_sh_entry {
- struct curl_hash transfers; /* hash of transfers using this socket */
+ struct Curl_hash transfers; /* hash of transfers using this socket */
unsigned int action; /* what combined action READ/WRITE this socket waits
for */
void *socketp; /* settable by users with curl_multi_assign() */
@@ -204,7 +204,7 @@ struct Curl_sh_entry {
#define SH_WRITE 2
/* look up a given socket in the socket hash, skip invalid sockets */
-static struct Curl_sh_entry *sh_getentry(struct curl_hash *sh,
+static struct Curl_sh_entry *sh_getentry(struct Curl_hash *sh,
curl_socket_t s)
{
if(s != CURL_SOCKET_BAD) {
@@ -238,7 +238,7 @@ static void trhash_dtor(void *nada)
/* make sure this socket is present in the hash for this handle */
-static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh,
+static struct Curl_sh_entry *sh_addentry(struct Curl_hash *sh,
curl_socket_t s)
{
struct Curl_sh_entry *there = sh_getentry(sh, s);
@@ -273,7 +273,7 @@ static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh,
/* delete the given socket + handle from the hash */
static void sh_delentry(struct Curl_sh_entry *entry,
- struct curl_hash *sh, curl_socket_t s)
+ struct Curl_hash *sh, curl_socket_t s)
{
Curl_hash_destroy(&entry->transfers);
@@ -325,7 +325,7 @@ static size_t hash_fd(void *key, size_t key_length, size_t slots_num)
* per call."
*
*/
-static int sh_init(struct curl_hash *hash, int hashsize)
+static int sh_init(struct Curl_hash *hash, int hashsize)
{
return Curl_hash_init(hash, hashsize, hash_fd, fd_key_compare,
sh_freeentry);
@@ -716,7 +716,7 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
struct Curl_easy *easy = data;
bool premature;
bool easy_owns_conn;
- struct curl_llist_element *e;
+ struct Curl_llist_element *e;
/* First, make some basic checks that the CURLM handle is a good handle */
if(!GOOD_MULTI_HANDLE(multi))
@@ -1081,11 +1081,11 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
unsigned int i;
unsigned int nfds = 0;
unsigned int curlfds;
- bool ufds_malloc = FALSE;
long timeout_internal;
int retcode = 0;
struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK];
struct pollfd *ufds = &a_few_on_stack[0];
+ bool ufds_malloc = FALSE;
if(!GOOD_MULTI_HANDLE(multi))
return CURLM_BAD_HANDLE;
@@ -1157,7 +1157,7 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
while(data) {
bitmap = multi_getsock(data, sockbunch);
- for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
+ for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) {
curl_socket_t s = CURL_SOCKET_BAD;
if(bitmap & GETSOCK_READSOCK(i)) {
@@ -1203,10 +1203,8 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
#endif
if(nfds) {
- int pollrc;
/* wait... */
- pollrc = Curl_poll(ufds, nfds, timeout_ms);
-
+ int pollrc = Curl_poll(ufds, nfds, timeout_ms);
if(pollrc > 0) {
retcode = pollrc;
/* copy revents results from the poll to the curl_multi_wait poll
@@ -1222,7 +1220,6 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
mask |= CURL_WAIT_POLLOUT;
if(r & POLLPRI)
mask |= CURL_WAIT_POLLPRI;
-
extra_fds[i].revents = mask;
}
@@ -1562,7 +1559,7 @@ CURLcode Curl_preconnect(struct Curl_easy *data)
static CURLMcode multi_runsingle(struct Curl_multi *multi,
- struct curltime now,
+ struct curltime *nowp,
struct Curl_easy *data)
{
struct Curl_message *msg = NULL;
@@ -1603,7 +1600,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
(data->mstate < CURLM_STATE_COMPLETED)) {
/* we need to wait for the connect state as only then is the start time
stored, but we must not check already completed handles */
- timeout_ms = Curl_timeleft(data, &now,
+ timeout_ms = Curl_timeleft(data, nowp,
(data->mstate <= CURLM_STATE_DO)?
TRUE:FALSE);
@@ -1612,25 +1609,25 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
if(data->mstate == CURLM_STATE_WAITRESOLVE)
failf(data, "Resolving timed out after %" CURL_FORMAT_TIMEDIFF_T
" milliseconds",
- Curl_timediff(now, data->progress.t_startsingle));
+ Curl_timediff(*nowp, data->progress.t_startsingle));
else if(data->mstate == CURLM_STATE_WAITCONNECT)
failf(data, "Connection timed out after %" CURL_FORMAT_TIMEDIFF_T
" milliseconds",
- Curl_timediff(now, data->progress.t_startsingle));
+ Curl_timediff(*nowp, data->progress.t_startsingle));
else {
struct SingleRequest *k = &data->req;
if(k->size != -1) {
failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T
" milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %"
CURL_FORMAT_CURL_OFF_T " bytes received",
- Curl_timediff(now, data->progress.t_startsingle),
+ Curl_timediff(*nowp, data->progress.t_startsingle),
k->bytecount, k->size);
}
else {
failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T
" milliseconds with %" CURL_FORMAT_CURL_OFF_T
" bytes received",
- Curl_timediff(now, data->progress.t_startsingle),
+ Curl_timediff(*nowp, data->progress.t_startsingle),
k->bytecount);
}
}
@@ -1655,7 +1652,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
if(!result) {
/* after init, go CONNECT */
multistate(data, CURLM_STATE_CONNECT);
- Curl_pgrsTime(data, TIMER_STARTOP);
+ *nowp = Curl_pgrsTime(data, TIMER_STARTOP);
rc = CURLM_CALL_MULTI_PERFORM;
}
break;
@@ -1672,7 +1669,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
if(result)
break;
- Curl_pgrsTime(data, TIMER_STARTSINGLE);
+ *nowp = Curl_pgrsTime(data, TIMER_STARTSINGLE);
if(data->set.timeout)
Curl_expire(data, data->set.timeout, EXPIRE_TIMEOUT);
@@ -2080,7 +2077,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
if(Curl_pgrsUpdate(data->conn))
result = CURLE_ABORTED_BY_CALLBACK;
else
- result = Curl_speedcheck(data, now);
+ result = Curl_speedcheck(data, *nowp);
if(!result) {
send_timeout_ms = 0;
@@ -2090,7 +2087,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
data->progress.ul_limit_size,
data->set.max_send_speed,
data->progress.ul_limit_start,
- now);
+ *nowp);
recv_timeout_ms = 0;
if(data->set.max_recv_speed > 0)
@@ -2099,11 +2096,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
data->progress.dl_limit_size,
data->set.max_recv_speed,
data->progress.dl_limit_start,
- now);
+ *nowp);
if(!send_timeout_ms && !recv_timeout_ms) {
multistate(data, CURLM_STATE_PERFORM);
- Curl_ratelimit(data, now);
+ Curl_ratelimit(data, *nowp);
}
else if(send_timeout_ms >= recv_timeout_ms)
Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
@@ -2125,7 +2122,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
data->progress.ul_limit_size,
data->set.max_send_speed,
data->progress.ul_limit_start,
- now);
+ *nowp);
/* check if over recv speed */
recv_timeout_ms = 0;
@@ -2134,10 +2131,10 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
data->progress.dl_limit_size,
data->set.max_recv_speed,
data->progress.dl_limit_start,
- now);
+ *nowp);
if(send_timeout_ms || recv_timeout_ms) {
- Curl_ratelimit(data, now);
+ Curl_ratelimit(data, *nowp);
multistate(data, CURLM_STATE_TOOFAST);
if(send_timeout_ms >= recv_timeout_ms)
Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
@@ -2417,7 +2414,7 @@ CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles)
SIGPIPE_VARIABLE(pipe_st);
sigpipe_ignore(data, &pipe_st);
- result = multi_runsingle(multi, now, data);
+ result = multi_runsingle(multi, &now, data);
sigpipe_restore(&pipe_st);
if(result)
@@ -2531,7 +2528,7 @@ CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue)
!multi->in_callback &&
Curl_llist_count(&multi->msglist)) {
/* there is one or more messages in the list */
- struct curl_llist_element *e;
+ struct Curl_llist_element *e;
/* extract the head of the list to return */
e = multi->msglist.head;
@@ -2761,15 +2758,15 @@ static CURLMcode add_next_timeout(struct curltime now,
struct Curl_easy *d)
{
struct curltime *tv = &d->state.expiretime;
- struct curl_llist *list = &d->state.timeoutlist;
- struct curl_llist_element *e;
+ struct Curl_llist *list = &d->state.timeoutlist;
+ struct Curl_llist_element *e;
struct time_node *node = NULL;
/* move over the timeout list for this specific handle and remove all
timeouts that are now passed tense and store the next pending
timeout in *tv */
for(e = list->head; e;) {
- struct curl_llist_element *n = e->next;
+ struct Curl_llist_element *n = e->next;
timediff_t diff;
node = (struct time_node *)e->ptr;
diff = Curl_timediff(node->time, now);
@@ -2839,8 +2836,8 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
and just move on. */
;
else {
- struct curl_hash_iterator iter;
- struct curl_hash_element *he;
+ struct Curl_hash_iterator iter;
+ struct Curl_hash_element *he;
/* the socket can be shared by many transfers, iterate */
Curl_hash_start_iterate(&entry->transfers, &iter);
@@ -2887,7 +2884,7 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
SIGPIPE_VARIABLE(pipe_st);
sigpipe_ignore(data, &pipe_st);
- result = multi_runsingle(multi, now, data);
+ result = multi_runsingle(multi, &now, data);
sigpipe_restore(&pipe_st);
if(CURLM_OK >= result) {
@@ -3015,7 +3012,6 @@ CURLMcode curl_multi_socket_action(struct Curl_multi *multi, curl_socket_t s,
}
CURLMcode curl_multi_socket_all(struct Curl_multi *multi, int *running_handles)
-
{
CURLMcode result;
if(multi->in_callback)
@@ -3123,8 +3119,8 @@ void Curl_update_timer(struct Curl_multi *multi)
static void
multi_deltimeout(struct Curl_easy *data, expire_id eid)
{
- struct curl_llist_element *e;
- struct curl_llist *timeoutlist = &data->state.timeoutlist;
+ struct Curl_llist_element *e;
+ struct Curl_llist *timeoutlist = &data->state.timeoutlist;
/* find and remove the specific node from the list */
for(e = timeoutlist->head; e; e = e->next) {
struct time_node *n = (struct time_node *)e->ptr;
@@ -3147,11 +3143,11 @@ multi_addtimeout(struct Curl_easy *data,
struct curltime *stamp,
expire_id eid)
{
- struct curl_llist_element *e;
+ struct Curl_llist_element *e;
struct time_node *node;
- struct curl_llist_element *prev = NULL;
+ struct Curl_llist_element *prev = NULL;
size_t n;
- struct curl_llist *timeoutlist = &data->state.timeoutlist;
+ struct Curl_llist *timeoutlist = &data->state.timeoutlist;
node = &data->state.expires[eid];
@@ -3233,9 +3229,8 @@ void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id id)
/* Since this is an updated time, we must remove the previous entry from
the splay tree first and then re-add the new value */
- rc = Curl_splayremovebyaddr(multi->timetree,
- &data->state.timenode,
- &multi->timetree);
+ rc = Curl_splayremove(multi->timetree, &data->state.timenode,
+ &multi->timetree);
if(rc)
infof(data, "Internal error removing splay node = %d\n", rc);
}
@@ -3278,12 +3273,11 @@ void Curl_expire_clear(struct Curl_easy *data)
if(nowp->tv_sec || nowp->tv_usec) {
/* Since this is an cleared time, we must remove the previous entry from
the splay tree */
- struct curl_llist *list = &data->state.timeoutlist;
+ struct Curl_llist *list = &data->state.timeoutlist;
int rc;
- rc = Curl_splayremovebyaddr(multi->timetree,
- &data->state.timenode,
- &multi->timetree);
+ rc = Curl_splayremove(multi->timetree, &data->state.timenode,
+ &multi->timetree);
if(rc)
infof(data, "Internal error clearing splay node = %d\n", rc);
@@ -3349,7 +3343,7 @@ void Curl_multiuse_state(struct connectdata *conn,
static void process_pending_handles(struct Curl_multi *multi)
{
- struct curl_llist_element *e = multi->pending.head;
+ struct Curl_llist_element *e = multi->pending.head;
if(e) {
struct Curl_easy *data = e->ptr;
diff --git a/lib/multihandle.h b/lib/multihandle.h
index 9d73df081..de4f74069 100644
--- a/lib/multihandle.h
+++ b/lib/multihandle.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -27,7 +27,7 @@
#include "socketpair.h"
struct Curl_message {
- struct curl_llist_element list;
+ struct Curl_llist_element list;
/* the 'CURLMsg' is the part that is visible to the external user */
struct CURLMsg extmsg;
};
@@ -67,11 +67,11 @@ typedef enum {
#define CURLPIPE_ANY (CURLPIPE_MULTIPLEX)
-#if defined(USE_SOCKETPAIR) && !defined(USE_BLOCKING_SOCKETS)
+#if defined(USE_SOCKETPAIR) && !defined(USE_BLOCKING_SOCKETS) && \
+ !defined(CURL_DISABLE_SOCKETPAIR)
#define ENABLE_WAKEUP
#endif
-
/* value for MAXIMUM CONCURRENT STREAMS upper limit */
#define INITIAL_MAX_CONCURRENT_STREAMS ((1U << 31) - 1)
@@ -89,9 +89,9 @@ struct Curl_multi {
int num_alive; /* amount of easy handles that are added but have not yet
reached COMPLETE state */
- struct curl_llist msglist; /* a list of messages from completed transfers */
+ struct Curl_llist msglist; /* a list of messages from completed transfers */
- struct curl_llist pending; /* Curl_easys that are in the
+ struct Curl_llist pending; /* Curl_easys that are in the
CURLM_STATE_CONNECT_PEND state */
/* callback function and user data pointer for the *socket() API */
@@ -103,7 +103,7 @@ struct Curl_multi {
void *push_userp;
/* Hostname cache */
- struct curl_hash hostcache;
+ struct Curl_hash hostcache;
#ifdef USE_LIBPSL
/* PSL cache. */
@@ -117,7 +117,7 @@ struct Curl_multi {
/* 'sockhash' is the lookup hash for socket descriptor => easy handles (note
the pluralis form, there can be more than one easy handle waiting on the
same actual socket) */
- struct curl_hash sockhash;
+ struct Curl_hash sockhash;
/* Shared connection cache (bundles)*/
struct conncache conn_cache;
diff --git a/lib/multiif.h b/lib/multiif.h
index 7d574df92..f0a57d9a6 100644
--- a/lib/multiif.h
+++ b/lib/multiif.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/netrc.c b/lib/netrc.c
index 326a2c674..fe51fda9e 100644
--- a/lib/netrc.c
+++ b/lib/netrc.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/netrc.h b/lib/netrc.h
index 7f56c4b4d..4938a5916 100644
--- a/lib/netrc.h
+++ b/lib/netrc.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/non-ascii.c b/lib/non-ascii.c
index 2b5d307e5..97436718f 100644
--- a/lib/non-ascii.c
+++ b/lib/non-ascii.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/non-ascii.h b/lib/non-ascii.h
index 5fb5771e0..458e8ef09 100644
--- a/lib/non-ascii.h
+++ b/lib/non-ascii.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/nonblock.c b/lib/nonblock.c
index abeb6598c..4a7bde504 100644
--- a/lib/nonblock.c
+++ b/lib/nonblock.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/nonblock.h b/lib/nonblock.h
index 6be2aea50..c4bfc8201 100644
--- a/lib/nonblock.h
+++ b/lib/nonblock.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/nwlib.c b/lib/nwlib.c
index beec0b388..769326892 100644
--- a/lib/nwlib.c
+++ b/lib/nwlib.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/nwos.c b/lib/nwos.c
index c6c22ccbb..889403132 100644
--- a/lib/nwos.c
+++ b/lib/nwos.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/openldap.c b/lib/openldap.c
index e50f8de14..ddc72eb43 100644
--- a/lib/openldap.c
+++ b/lib/openldap.c
@@ -10,7 +10,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -107,6 +107,7 @@ const struct Curl_handler Curl_handler_ldap = {
ZERO_NULL, /* connection_check */
PORT_LDAP, /* defport */
CURLPROTO_LDAP, /* protocol */
+ CURLPROTO_LDAP, /* family */
PROTOPT_NONE /* flags */
};
@@ -132,7 +133,8 @@ const struct Curl_handler Curl_handler_ldaps = {
ZERO_NULL, /* readwrite */
ZERO_NULL, /* connection_check */
PORT_LDAPS, /* defport */
- CURLPROTO_LDAP, /* protocol */
+ CURLPROTO_LDAPS, /* protocol */
+ CURLPROTO_LDAP, /* family */
PROTOPT_SSL /* flags */
};
#endif
@@ -410,7 +412,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done)
if(!lr)
return CURLE_OUT_OF_MEMORY;
lr->msgid = msgid;
- data->req.protop = lr;
+ data->req.p.ldap = lr;
Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1);
*done = TRUE;
return CURLE_OK;
@@ -419,7 +421,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done)
static CURLcode ldap_done(struct connectdata *conn, CURLcode res,
bool premature)
{
- struct ldapreqinfo *lr = conn->data->req.protop;
+ struct ldapreqinfo *lr = conn->data->req.p.ldap;
(void)res;
(void)premature;
@@ -431,7 +433,7 @@ static CURLcode ldap_done(struct connectdata *conn, CURLcode res,
ldap_abandon_ext(li->ld, lr->msgid, NULL, NULL);
lr->msgid = 0;
}
- conn->data->req.protop = NULL;
+ conn->data->req.p.ldap = NULL;
free(lr);
}
@@ -443,7 +445,7 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
{
struct ldapconninfo *li = conn->proto.ldapc;
struct Curl_easy *data = conn->data;
- struct ldapreqinfo *lr = data->req.protop;
+ struct ldapreqinfo *lr = data->req.p.ldap;
int rc, ret;
LDAPMessage *msg = NULL;
LDAPMessage *ent;
diff --git a/lib/optiontable.pl b/lib/optiontable.pl
new file mode 100644
index 000000000..31cfbcee6
--- /dev/null
+++ b/lib/optiontable.pl
@@ -0,0 +1,118 @@
+#!/usr/bin/perl
+
+print <<HEAD
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* This source code is generated by optiontable.pl - DO NOT EDIT BY HAND */
+
+#include "curl_setup.h"
+#include "easyoptions.h"
+
+/* all easy setopt options listed in alphabetical order */
+struct curl_easyoption Curl_easyopts[] = {
+HEAD
+ ;
+
+my $lastnum=0;
+
+while(<STDIN>) {
+ if(/^ *CURLOPT\(([^,]*), ([^,]*), (\d+)\)/) {
+ my($opt, $type, $num)=($1,$2,$3);
+ my $name;
+ my $ext = $type;
+
+ if($opt =~ /OBSOLETE/) {
+ # skip obsolete options
+ next;
+ }
+
+ if($opt =~ /^CURLOPT_(.*)/) {
+ $name=$1;
+ }
+ $ext =~ s/CURLOPTTYPE_//;
+ $ext =~ s/CBPOINT/CBPTR/;
+ $ext =~ s/POINT\z//;
+ $type = "CURLOT_$ext";
+
+ $opt{$name} = $opt;
+ $type{$name} = $type;
+ push @names, $name;
+ if($num < $lastnum) {
+ print STDERR "ERROR: $opt has bad number\n";
+ exit 2;
+ }
+ else {
+ $lastnum = $num;
+ }
+ }
+
+ # alias for an older option
+ # old = new
+ if(/^#define (CURLOPT_[^ ]*) *(CURLOPT_\S*)/) {
+ my ($o, $n)=($1, $2);
+ # skip obsolete ones
+ if($n !~ /OBSOLETE/) {
+ $o =~ s/^CURLOPT_//;
+ $n =~ s/^CURLOPT_//;
+ $alias{$o} = $n;
+ push @names, $o,
+ }
+ }
+}
+
+
+for my $name (sort @names) {
+ my $oname = $name;
+ my $a = $alias{$name};
+ my $flag = "0";
+ if($a) {
+ $name = $alias{$name};
+ $flag = "CURLOT_FLAG_ALIAS";
+ }
+ $o = sprintf(" {\"%s\", %s, %s, %s},\n",
+ $oname, $opt{$name}, $type{$name}, $flag);
+ if(length($o) < 80) {
+ print $o;
+ }
+ else {
+ printf(" {\"%s\", %s,\n %s, %s},\n",
+ $oname, $opt{$name}, $type{$name}, $flag);
+ }
+}
+
+print <<FOOT
+ {NULL, CURLOPT_LASTENTRY, 0, 0} /* end of table */
+};
+
+#ifdef DEBUGBUILD
+/*
+ * Curl_easyopts_check() is a debug-only function that returns non-zero
+ * if this source file is not in sync with the options listed in curl/curl.h
+ */
+int Curl_easyopts_check(void)
+{
+ return (CURLOPT_LASTENTRY != ($lastnum + 1));
+}
+#endif
+FOOT
+ ;
diff --git a/lib/parsedate.c b/lib/parsedate.c
index e233550e7..a1593ec74 100644
--- a/lib/parsedate.c
+++ b/lib/parsedate.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -275,48 +275,21 @@ enum assume {
DATE_TIME
};
-/* this is a clone of 'struct tm' but with all fields we don't need or use
- cut out */
-struct my_tm {
- int tm_sec;
- int tm_min;
- int tm_hour;
- int tm_mday;
- int tm_mon;
- int tm_year; /* full year */
-};
-
-/* struct tm to time since epoch in GMT time zone.
- * This is similar to the standard mktime function but for GMT only, and
- * doesn't suffer from the various bugs and portability problems that
- * some systems' implementations have.
- *
- * Returns 0 on success, otherwise non-zero.
+/*
+ * time2epoch: time stamp to seconds since epoch in GMT time zone. Similar to
+ * mktime but for GMT only.
*/
-static void my_timegm(struct my_tm *tm, time_t *t)
+static time_t time2epoch(int sec, int min, int hour,
+ int mday, int mon, int year)
{
static const int month_days_cumulative [12] =
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
- int month, year, leap_days;
-
- year = tm->tm_year;
- month = tm->tm_mon;
- if(month < 0) {
- year += (11 - month) / 12;
- month = 11 - (11 - month) % 12;
- }
- else if(month >= 12) {
- year -= month / 12;
- month = month % 12;
- }
-
- leap_days = year - (tm->tm_mon <= 1);
+ int leap_days = year - (mon <= 1);
leap_days = ((leap_days / 4) - (leap_days / 100) + (leap_days / 400)
- (1969 / 4) + (1969 / 100) - (1969 / 400));
-
- *t = ((((time_t) (year - 1970) * 365
- + leap_days + month_days_cumulative[month] + tm->tm_mday - 1) * 24
- + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec;
+ return ((((time_t) (year - 1970) * 365
+ + leap_days + month_days_cumulative[mon] + mday - 1) * 24
+ + hour) * 60 + min) * 60 + sec;
}
/*
@@ -341,7 +314,6 @@ static int parsedate(const char *date, time_t *output)
int secnum = -1;
int yearnum = -1;
int tzoff = -1;
- struct my_tm tm;
enum assume dignext = DATE_MDAY;
const char *indate = date; /* save the original pointer */
int part = 0; /* max 6 parts */
@@ -533,18 +505,11 @@ static int parsedate(const char *date, time_t *output)
(hournum > 23) || (minnum > 59) || (secnum > 60))
return PARSEDATE_FAIL; /* clearly an illegal date */
- tm.tm_sec = secnum;
- tm.tm_min = minnum;
- tm.tm_hour = hournum;
- tm.tm_mday = mdaynum;
- tm.tm_mon = monnum;
- tm.tm_year = yearnum;
-
- /* my_timegm() returns a time_t. time_t is often 32 bits, sometimes even on
+ /* time2epoch() returns a time_t. time_t is often 32 bits, sometimes even on
architectures that feature 64 bit 'long' but ultimately time_t is the
correct data type to use.
*/
- my_timegm(&tm, &t);
+ t = time2epoch(secnum, minnum, hournum, mdaynum, monnum, yearnum);
/* Add the time zone diff between local time zone and GMT. */
if(tzoff == -1)
diff --git a/lib/parsedate.h b/lib/parsedate.h
index 8c7ae94e4..a99faf9e3 100644
--- a/lib/parsedate.h
+++ b/lib/parsedate.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/pingpong.c b/lib/pingpong.c
index 314331521..5d6109a7d 100644
--- a/lib/pingpong.c
+++ b/lib/pingpong.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -146,7 +146,11 @@ void Curl_pp_init(struct pingpong *pp)
pp->response = Curl_now(); /* start response time-out now! */
}
-
+/* setup for the coming transfer */
+void Curl_pp_setup(struct pingpong *pp)
+{
+ Curl_dyn_init(&pp->sendbuf, DYN_PINGPPONG_CMD);
+}
/***********************************************************************
*
@@ -162,9 +166,8 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp,
const char *fmt,
va_list args)
{
- ssize_t bytes_written;
+ ssize_t bytes_written = 0;
size_t write_len;
- char *fmt_crlf;
char *s;
CURLcode result;
struct connectdata *conn = pp->conn;
@@ -181,48 +184,41 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp,
if(!conn)
/* can't send without a connection! */
return CURLE_SEND_ERROR;
-
data = conn->data;
- fmt_crlf = aprintf("%s\r\n", fmt); /* append a trailing CRLF */
- if(!fmt_crlf)
- return CURLE_OUT_OF_MEMORY;
-
- s = vaprintf(fmt_crlf, args); /* trailing CRLF appended */
- free(fmt_crlf);
- if(!s)
- return CURLE_OUT_OF_MEMORY;
+ Curl_dyn_reset(&pp->sendbuf);
+ result = Curl_dyn_vaddf(&pp->sendbuf, fmt, args);
+ if(result)
+ return result;
- bytes_written = 0;
- write_len = strlen(s);
+ /* append CRLF */
+ result = Curl_dyn_addn(&pp->sendbuf, "\r\n", 2);
+ if(result)
+ return result;
+ write_len = Curl_dyn_len(&pp->sendbuf);
+ s = Curl_dyn_ptr(&pp->sendbuf);
Curl_pp_init(pp);
result = Curl_convert_to_network(data, s, write_len);
/* Curl_convert_to_network calls failf if unsuccessful */
- if(result) {
- free(s);
+ if(result)
return result;
- }
#ifdef HAVE_GSSAPI
conn->data_prot = PROT_CMD;
#endif
result = Curl_write(conn, conn->sock[FIRSTSOCKET], s, write_len,
- &bytes_written);
+ &bytes_written);
+ if(result)
+ return result;
#ifdef HAVE_GSSAPI
data_sec = conn->data_prot;
DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST);
conn->data_prot = data_sec;
#endif
- if(result) {
- free(s);
- return result;
- }
-
- if(conn->data->set.verbose)
- Curl_debug(conn->data, CURLINFO_HEADER_OUT, s, (size_t)bytes_written);
+ Curl_debug(data, CURLINFO_HEADER_OUT, s, (size_t)bytes_written);
if(bytes_written != (ssize_t)write_len) {
/* the whole chunk was not sent, keep it around and adjust sizes */
@@ -231,7 +227,6 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp,
pp->sendleft = write_len - bytes_written;
}
else {
- free(s);
pp->sendthis = NULL;
pp->sendleft = pp->sendsize = 0;
pp->response = Curl_now();
@@ -368,9 +363,8 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd,
#ifdef HAVE_GSSAPI
if(!conn->sec_complete)
#endif
- if(data->set.verbose)
- Curl_debug(data, CURLINFO_HEADER_IN,
- pp->linestart_resp, (size_t)perline);
+ Curl_debug(data, CURLINFO_HEADER_IN,
+ pp->linestart_resp, (size_t)perline);
/*
* We pass all response-lines to the callback function registered
@@ -493,7 +487,6 @@ CURLcode Curl_pp_flushsend(struct pingpong *pp)
pp->sendleft -= written;
}
else {
- free(pp->sendthis);
pp->sendthis = NULL;
pp->sendleft = pp->sendsize = 0;
pp->response = Curl_now();
@@ -503,15 +496,15 @@ CURLcode Curl_pp_flushsend(struct pingpong *pp)
CURLcode Curl_pp_disconnect(struct pingpong *pp)
{
- free(pp->cache);
- pp->cache = NULL;
+ Curl_dyn_free(&pp->sendbuf);
+ Curl_safefree(pp->cache);
return CURLE_OK;
}
bool Curl_pp_moredata(struct pingpong *pp)
{
return (!pp->sendleft && pp->cache && pp->nread_resp < pp->cache_size) ?
- TRUE : FALSE;
+ TRUE : FALSE;
}
#endif
diff --git a/lib/pingpong.h b/lib/pingpong.h
index e874799d4..0d0c74afa 100644
--- a/lib/pingpong.h
+++ b/lib/pingpong.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -64,6 +64,7 @@ struct pingpong {
milliseconds we await for a server response. */
struct connectdata *conn; /* points to the connectdata struct that this
belongs to */
+ struct dynbuf sendbuf;
/* Function pointers the protocols MUST implement and provide for the
pingpong layer to function */
@@ -86,6 +87,9 @@ CURLcode Curl_pp_statemach(struct pingpong *pp, bool block,
/* initialize stuff to prepare for reading a fresh new response */
void Curl_pp_init(struct pingpong *pp);
+/* setup for the transfer */
+void Curl_pp_setup(struct pingpong *pp);
+
/* Returns timeout in ms. 0 or negative number means the timeout has already
triggered */
timediff_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting);
diff --git a/lib/pop3.c b/lib/pop3.c
index cc88df756..7af51e8d7 100644
--- a/lib/pop3.c
+++ b/lib/pop3.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -128,6 +128,7 @@ const struct Curl_handler Curl_handler_pop3 = {
ZERO_NULL, /* connection_check */
PORT_POP3, /* defport */
CURLPROTO_POP3, /* protocol */
+ CURLPROTO_POP3, /* family */
PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
PROTOPT_URLOPTIONS
};
@@ -155,6 +156,7 @@ const struct Curl_handler Curl_handler_pop3s = {
ZERO_NULL, /* connection_check */
PORT_POP3S, /* defport */
CURLPROTO_POP3S, /* protocol */
+ CURLPROTO_POP3, /* family */
PROTOPT_CLOSEACTION | PROTOPT_SSL
| PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS /* flags */
};
@@ -551,7 +553,7 @@ static CURLcode pop3_perform_command(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct POP3 *pop3 = data->req.protop;
+ struct POP3 *pop3 = data->req.p.pop3;
const char *command = NULL;
/* Calculate the default command */
@@ -884,7 +886,7 @@ static CURLcode pop3_state_command_resp(struct connectdata *conn,
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct POP3 *pop3 = data->req.protop;
+ struct POP3 *pop3 = data->req.p.pop3;
struct pop3_conn *pop3c = &conn->proto.pop3c;
struct pingpong *pp = &pop3c->pp;
@@ -1046,7 +1048,7 @@ static CURLcode pop3_init(struct connectdata *conn)
struct Curl_easy *data = conn->data;
struct POP3 *pop3;
- pop3 = data->req.protop = calloc(sizeof(struct POP3), 1);
+ pop3 = data->req.p.pop3 = calloc(sizeof(struct POP3), 1);
if(!pop3)
result = CURLE_OUT_OF_MEMORY;
@@ -1091,6 +1093,7 @@ static CURLcode pop3_connect(struct connectdata *conn, bool *done)
Curl_sasl_init(&pop3c->sasl, &saslpop3);
/* Initialise the pingpong layer */
+ Curl_pp_setup(pp);
Curl_pp_init(pp);
/* Parse the URL options */
@@ -1120,7 +1123,7 @@ static CURLcode pop3_done(struct connectdata *conn, CURLcode status,
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct POP3 *pop3 = data->req.protop;
+ struct POP3 *pop3 = data->req.p.pop3;
(void)premature;
@@ -1154,7 +1157,7 @@ static CURLcode pop3_perform(struct connectdata *conn, bool *connected,
{
/* This is POP3 and no proxy */
CURLcode result = CURLE_OK;
- struct POP3 *pop3 = conn->data->req.protop;
+ struct POP3 *pop3 = conn->data->req.p.pop3;
DEBUGF(infof(conn->data, "DO phase starts\n"));
@@ -1386,7 +1389,7 @@ static CURLcode pop3_parse_url_path(struct connectdata *conn)
{
/* The POP3 struct is already initialised in pop3_connect() */
struct Curl_easy *data = conn->data;
- struct POP3 *pop3 = data->req.protop;
+ struct POP3 *pop3 = data->req.p.pop3;
const char *path = &data->state.up.path[1]; /* skip leading path */
/* URL decode the path for the message ID */
@@ -1403,7 +1406,7 @@ static CURLcode pop3_parse_custom_request(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct POP3 *pop3 = data->req.protop;
+ struct POP3 *pop3 = data->req.p.pop3;
const char *custom = data->set.str[STRING_CUSTOMREQUEST];
/* URL decode the custom request */
diff --git a/lib/pop3.h b/lib/pop3.h
index 3ba799977..6ca3fd511 100644
--- a/lib/pop3.h
+++ b/lib/pop3.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2009 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2009 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/progress.c b/lib/progress.c
index 895138448..658d05ab8 100644
--- a/lib/progress.c
+++ b/lib/progress.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -164,9 +164,13 @@ void Curl_pgrsResetTransferSizes(struct Curl_easy *data)
}
/*
+ *
+ * Curl_pgrsTime(). Store the current time at the given label. This fetches a
+ * fresh "now" and returns it.
+ *
* @unittest: 1399
*/
-void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
+struct curltime Curl_pgrsTime(struct Curl_easy *data, timerid timer)
{
struct curltime now = Curl_now();
timediff_t *delta = NULL;
@@ -209,7 +213,7 @@ void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
* changing the t_starttransfer time.
*/
if(data->progress.is_t_startransfer_set) {
- return;
+ return now;
}
else {
data->progress.is_t_startransfer_set = true;
@@ -228,6 +232,7 @@ void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
us = 1; /* make sure at least one microsecond passed */
*delta += us;
}
+ return now;
}
void Curl_pgrsStartNow(struct Curl_easy *data)
@@ -235,10 +240,8 @@ void Curl_pgrsStartNow(struct Curl_easy *data)
data->progress.speeder_c = 0; /* reset the progress meter display */
data->progress.start = Curl_now();
data->progress.is_t_startransfer_set = false;
- data->progress.ul_limit_start.tv_sec = 0;
- data->progress.ul_limit_start.tv_usec = 0;
- data->progress.dl_limit_start.tv_sec = 0;
- data->progress.dl_limit_start.tv_usec = 0;
+ data->progress.ul_limit_start = data->progress.start;
+ data->progress.dl_limit_start = data->progress.start;
data->progress.downloaded = 0;
data->progress.uploaded = 0;
/* clear all bits except HIDE and HEADERS_OUT */
diff --git a/lib/progress.h b/lib/progress.h
index 3515ac6d5..74680099f 100644
--- a/lib/progress.h
+++ b/lib/progress.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -49,7 +49,7 @@ void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size);
void Curl_ratelimit(struct Curl_easy *data, struct curltime now);
int Curl_pgrsUpdate(struct connectdata *);
void Curl_pgrsResetTransferSizes(struct Curl_easy *data);
-void Curl_pgrsTime(struct Curl_easy *data, timerid timer);
+struct curltime Curl_pgrsTime(struct Curl_easy *data, timerid timer);
timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize,
curl_off_t startsize,
curl_off_t limit,
diff --git a/lib/psl.c b/lib/psl.c
index d50c6250f..0d0db86e8 100644
--- a/lib/psl.c
+++ b/lib/psl.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/psl.h b/lib/psl.h
index e9f99d03e..c10367471 100644
--- a/lib/psl.h
+++ b/lib/psl.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/quic.h b/lib/quic.h
index 8e7df90ea..f04662e82 100644
--- a/lib/quic.h
+++ b/lib/quic.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -41,7 +41,7 @@ CURLcode Curl_quic_connect(struct connectdata *conn,
const struct sockaddr *addr,
socklen_t addrlen);
CURLcode Curl_quic_is_connected(struct connectdata *conn,
- curl_socket_t sockfd,
+ int sockindex,
bool *connected);
int Curl_quic_ver(char *p, size_t len);
CURLcode Curl_quic_done_sending(struct connectdata *conn);
diff --git a/lib/rand.c b/lib/rand.c
index d470c24be..626287334 100644
--- a/lib/rand.c
+++ b/lib/rand.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/rand.h b/lib/rand.h
index 3c8e2b81d..02d95d8e6 100644
--- a/lib/rand.h
+++ b/lib/rand.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/rename.c b/lib/rename.c
index fe5f95d0d..f858d4369 100644
--- a/lib/rename.c
+++ b/lib/rename.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -24,8 +24,8 @@
#include "curl_setup.h"
-#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)) || \
- defined(USE_ALTSVC)
+#if (!defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_COOKIES)) || \
+ !defined(CURL_DISABLE_ALTSVC)
#include "curl_multibyte.h"
#include "timeval.h"
diff --git a/lib/rename.h b/lib/rename.h
index d7442c844..534f7471c 100644
--- a/lib/rename.h
+++ b/lib/rename.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/rtsp.c b/lib/rtsp.c
index 02cae53c7..47d67caf0 100644
--- a/lib/rtsp.c
+++ b/lib/rtsp.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -106,6 +106,7 @@ const struct Curl_handler Curl_handler_rtsp = {
rtsp_conncheck, /* connection_check */
PORT_RTSP, /* defport */
CURLPROTO_RTSP, /* protocol */
+ CURLPROTO_RTSP, /* family */
PROTOPT_NONE /* flags */
};
@@ -114,7 +115,7 @@ static CURLcode rtsp_setup_connection(struct connectdata *conn)
{
struct RTSP *rtsp;
- conn->data->req.protop = rtsp = calloc(1, sizeof(struct RTSP));
+ conn->data->req.p.rtsp = rtsp = calloc(1, sizeof(struct RTSP));
if(!rtsp)
return CURLE_OUT_OF_MEMORY;
@@ -199,7 +200,7 @@ static CURLcode rtsp_done(struct connectdata *conn,
CURLcode status, bool premature)
{
struct Curl_easy *data = conn->data;
- struct RTSP *rtsp = data->req.protop;
+ struct RTSP *rtsp = data->req.p.rtsp;
CURLcode httpStatus;
/* Bypass HTTP empty-reply checks on receive */
@@ -232,7 +233,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
struct Curl_easy *data = conn->data;
CURLcode result = CURLE_OK;
Curl_RtspReq rtspreq = data->set.rtspreq;
- struct RTSP *rtsp = data->req.protop;
+ struct RTSP *rtsp = data->req.p.rtsp;
struct dynbuf req_buffer;
curl_off_t postsize = 0; /* for ANNOUNCE and SET_PARAMETER */
curl_off_t putsize = 0; /* for ANNOUNCE and SET_PARAMETER */
@@ -764,7 +765,7 @@ CURLcode Curl_rtsp_parseheader(struct connectdata *conn,
/* Store the received CSeq. Match is verified in rtsp_done */
int nc = sscanf(&header[4], ": %ld", &CSeq);
if(nc == 1) {
- struct RTSP *rtsp = data->req.protop;
+ struct RTSP *rtsp = data->req.p.rtsp;
rtsp->CSeq_recv = CSeq; /* mark the request */
data->state.rtsp_CSeq_recv = CSeq; /* update the handle */
}
@@ -775,6 +776,8 @@ CURLcode Curl_rtsp_parseheader(struct connectdata *conn,
}
else if(checkprefix("Session:", header)) {
char *start;
+ char *end;
+ size_t idlen;
/* Find the first non-space letter */
start = header + 8;
@@ -783,11 +786,25 @@ CURLcode Curl_rtsp_parseheader(struct connectdata *conn,
if(!*start) {
failf(data, "Got a blank Session ID");
+ return CURLE_RTSP_SESSION_ERROR;
}
- else if(data->set.str[STRING_RTSP_SESSION_ID]) {
+
+ /* Find the end of Session ID
+ *
+ * Allow any non whitespace content, up to the field separator or end of
+ * line. RFC 2326 isn't 100% clear on the session ID and for example
+ * gstreamer does url-encoded session ID's not covered by the standard.
+ */
+ end = start;
+ while(*end && *end != ';' && !ISSPACE(*end))
+ end++;
+ idlen = end - start;
+
+ if(data->set.str[STRING_RTSP_SESSION_ID]) {
+
/* If the Session ID is set, then compare */
- if(strncmp(start, data->set.str[STRING_RTSP_SESSION_ID],
- strlen(data->set.str[STRING_RTSP_SESSION_ID])) != 0) {
+ if(strlen(data->set.str[STRING_RTSP_SESSION_ID]) != idlen ||
+ strncmp(start, data->set.str[STRING_RTSP_SESSION_ID], idlen) != 0) {
failf(data, "Got RTSP Session ID Line [%s], but wanted ID [%s]",
start, data->set.str[STRING_RTSP_SESSION_ID]);
return CURLE_RTSP_SESSION_ERROR;
@@ -796,21 +813,14 @@ CURLcode Curl_rtsp_parseheader(struct connectdata *conn,
else {
/* If the Session ID is not set, and we find it in a response, then set
* it.
- *
- * Allow any non whitespace content, up to the field separator or end of
- * line. RFC 2326 isn't 100% clear on the session ID and for example
- * gstreamer does url-encoded session ID's not covered by the standard.
*/
- char *end = start;
- while(*end && *end != ';' && !ISSPACE(*end))
- end++;
/* Copy the id substring into a new buffer */
- data->set.str[STRING_RTSP_SESSION_ID] = malloc(end - start + 1);
+ data->set.str[STRING_RTSP_SESSION_ID] = malloc(idlen + 1);
if(data->set.str[STRING_RTSP_SESSION_ID] == NULL)
return CURLE_OUT_OF_MEMORY;
- memcpy(data->set.str[STRING_RTSP_SESSION_ID], start, end - start);
- (data->set.str[STRING_RTSP_SESSION_ID])[end - start] = '\0';
+ memcpy(data->set.str[STRING_RTSP_SESSION_ID], start, idlen);
+ (data->set.str[STRING_RTSP_SESSION_ID])[idlen] = '\0';
}
}
return CURLE_OK;
diff --git a/lib/rtsp.h b/lib/rtsp.h
index 1aae86456..bf7f0bc8e 100644
--- a/lib/rtsp.h
+++ b/lib/rtsp.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/security.c b/lib/security.c
deleted file mode 100644
index fbfa70741..000000000
--- a/lib/security.c
+++ /dev/null
@@ -1,579 +0,0 @@
-/* This source code was modified by Martin Hedenfalk <mhe@stacken.kth.se> for
- * use in Curl. His latest changes were done 2000-09-18.
- *
- * It has since been patched and modified a lot by Daniel Stenberg
- * <daniel@haxx.se> to make it better applied to curl conditions, and to make
- * it not use globals, pollute name space and more. This source code awaits a
- * rewrite to work around the paragraph 2 in the BSD licenses as explained
- * below.
- *
- * Copyright (c) 1998, 1999, 2017 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- *
- * Copyright (C) 2001 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * 3. Neither the name of the Institute nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE. */
-
-#include "curl_setup.h"
-
-#ifndef CURL_DISABLE_FTP
-#ifdef HAVE_GSSAPI
-
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-
-#include <limits.h>
-
-#include "urldata.h"
-#include "curl_base64.h"
-#include "curl_memory.h"
-#include "curl_sec.h"
-#include "ftp.h"
-#include "sendf.h"
-#include "strcase.h"
-#include "warnless.h"
-#include "strdup.h"
-/* The last 3 #include files should be in this order */
-#include "curl_printf.h"
-#include "curl_memory.h"
-#include "memdebug.h"
-
-static const struct {
- enum protection_level level;
- const char *name;
-} level_names[] = {
- { PROT_CLEAR, "clear" },
- { PROT_SAFE, "safe" },
- { PROT_CONFIDENTIAL, "confidential" },
- { PROT_PRIVATE, "private" }
-};
-
-static enum protection_level
-name_to_level(const char *name)
-{
- int i;
- for(i = 0; i < (int)sizeof(level_names)/(int)sizeof(level_names[0]); i++)
- if(checkprefix(name, level_names[i].name))
- return level_names[i].level;
- return PROT_NONE;
-}
-
-/* Convert a protocol |level| to its char representation.
- We take an int to catch programming mistakes. */
-static char level_to_char(int level)
-{
- switch(level) {
- case PROT_CLEAR:
- return 'C';
- case PROT_SAFE:
- return 'S';
- case PROT_CONFIDENTIAL:
- return 'E';
- case PROT_PRIVATE:
- return 'P';
- case PROT_CMD:
- /* Fall through */
- default:
- /* Those 2 cases should not be reached! */
- break;
- }
- DEBUGASSERT(0);
- /* Default to the most secure alternative. */
- return 'P';
-}
-
-/* Send an FTP command defined by |message| and the optional arguments. The
- function returns the ftp_code. If an error occurs, -1 is returned. */
-static int ftp_send_command(struct connectdata *conn, const char *message, ...)
-{
- int ftp_code;
- ssize_t nread = 0;
- va_list args;
- char print_buffer[50];
-
- va_start(args, message);
- mvsnprintf(print_buffer, sizeof(print_buffer), message, args);
- va_end(args);
-
- if(Curl_ftpsend(conn, print_buffer)) {
- ftp_code = -1;
- }
- else {
- if(Curl_GetFTPResponse(&nread, conn, &ftp_code))
- ftp_code = -1;
- }
-
- (void)nread; /* Unused */
- return ftp_code;
-}
-
-/* Read |len| from the socket |fd| and store it in |to|. Return a CURLcode
- saying whether an error occurred or CURLE_OK if |len| was read. */
-static CURLcode
-socket_read(curl_socket_t fd, void *to, size_t len)
-{
- char *to_p = to;
- CURLcode result;
- ssize_t nread = 0;
-
- while(len > 0) {
- result = Curl_read_plain(fd, to_p, len, &nread);
- if(!result) {
- len -= nread;
- to_p += nread;
- }
- else {
- if(result == CURLE_AGAIN)
- continue;
- return result;
- }
- }
- return CURLE_OK;
-}
-
-
-/* Write |len| bytes from the buffer |to| to the socket |fd|. Return a
- CURLcode saying whether an error occurred or CURLE_OK if |len| was
- written. */
-static CURLcode
-socket_write(struct connectdata *conn, curl_socket_t fd, const void *to,
- size_t len)
-{
- const char *to_p = to;
- CURLcode result;
- ssize_t written;
-
- while(len > 0) {
- result = Curl_write_plain(conn, fd, to_p, len, &written);
- if(!result) {
- len -= written;
- to_p += written;
- }
- else {
- if(result == CURLE_AGAIN)
- continue;
- return result;
- }
- }
- return CURLE_OK;
-}
-
-static CURLcode read_data(struct connectdata *conn,
- curl_socket_t fd,
- struct krb5buffer *buf)
-{
- int len;
- CURLcode result;
-
- result = socket_read(fd, &len, sizeof(len));
- if(result)
- return result;
-
- if(len) {
- /* only realloc if there was a length */
- len = ntohl(len);
- buf->data = Curl_saferealloc(buf->data, len);
- }
- if(!len || !buf->data)
- return CURLE_OUT_OF_MEMORY;
-
- result = socket_read(fd, buf->data, len);
- if(result)
- return result;
- buf->size = conn->mech->decode(conn->app_data, buf->data, len,
- conn->data_prot, conn);
- buf->index = 0;
- return CURLE_OK;
-}
-
-static size_t
-buffer_read(struct krb5buffer *buf, void *data, size_t len)
-{
- if(buf->size - buf->index < len)
- len = buf->size - buf->index;
- memcpy(data, (char *)buf->data + buf->index, len);
- buf->index += len;
- return len;
-}
-
-/* Matches Curl_recv signature */
-static ssize_t sec_recv(struct connectdata *conn, int sockindex,
- char *buffer, size_t len, CURLcode *err)
-{
- size_t bytes_read;
- size_t total_read = 0;
- curl_socket_t fd = conn->sock[sockindex];
-
- *err = CURLE_OK;
-
- /* Handle clear text response. */
- if(conn->sec_complete == 0 || conn->data_prot == PROT_CLEAR)
- return sread(fd, buffer, len);
-
- if(conn->in_buffer.eof_flag) {
- conn->in_buffer.eof_flag = 0;
- return 0;
- }
-
- bytes_read = buffer_read(&conn->in_buffer, buffer, len);
- len -= bytes_read;
- total_read += bytes_read;
- buffer += bytes_read;
-
- while(len > 0) {
- if(read_data(conn, fd, &conn->in_buffer))
- return -1;
- if(conn->in_buffer.size == 0) {
- if(bytes_read > 0)
- conn->in_buffer.eof_flag = 1;
- return bytes_read;
- }
- bytes_read = buffer_read(&conn->in_buffer, buffer, len);
- len -= bytes_read;
- total_read += bytes_read;
- buffer += bytes_read;
- }
- return total_read;
-}
-
-/* Send |length| bytes from |from| to the |fd| socket taking care of encoding
- and negotiating with the server. |from| can be NULL. */
-static void do_sec_send(struct connectdata *conn, curl_socket_t fd,
- const char *from, int length)
-{
- int bytes, htonl_bytes; /* 32-bit integers for htonl */
- char *buffer = NULL;
- char *cmd_buffer;
- size_t cmd_size = 0;
- CURLcode error;
- enum protection_level prot_level = conn->data_prot;
- bool iscmd = (prot_level == PROT_CMD)?TRUE:FALSE;
-
- DEBUGASSERT(prot_level > PROT_NONE && prot_level < PROT_LAST);
-
- if(iscmd) {
- if(!strncmp(from, "PASS ", 5) || !strncmp(from, "ACCT ", 5))
- prot_level = PROT_PRIVATE;
- else
- prot_level = conn->command_prot;
- }
- bytes = conn->mech->encode(conn->app_data, from, length, prot_level,
- (void **)&buffer);
- if(!buffer || bytes <= 0)
- return; /* error */
-
- if(iscmd) {
- error = Curl_base64_encode(conn->data, buffer, curlx_sitouz(bytes),
- &cmd_buffer, &cmd_size);
- if(error) {
- free(buffer);
- return; /* error */
- }
- if(cmd_size > 0) {
- static const char *enc = "ENC ";
- static const char *mic = "MIC ";
- if(prot_level == PROT_PRIVATE)
- socket_write(conn, fd, enc, 4);
- else
- socket_write(conn, fd, mic, 4);
-
- socket_write(conn, fd, cmd_buffer, cmd_size);
- socket_write(conn, fd, "\r\n", 2);
- infof(conn->data, "Send: %s%s\n", prot_level == PROT_PRIVATE?enc:mic,
- cmd_buffer);
- free(cmd_buffer);
- }
- }
- else {
- htonl_bytes = htonl(bytes);
- socket_write(conn, fd, &htonl_bytes, sizeof(htonl_bytes));
- socket_write(conn, fd, buffer, curlx_sitouz(bytes));
- }
- free(buffer);
-}
-
-static ssize_t sec_write(struct connectdata *conn, curl_socket_t fd,
- const char *buffer, size_t length)
-{
- ssize_t tx = 0, len = conn->buffer_size;
-
- len -= conn->mech->overhead(conn->app_data, conn->data_prot,
- curlx_sztosi(len));
- if(len <= 0)
- len = length;
- while(length) {
- if(length < (size_t)len)
- len = length;
-
- do_sec_send(conn, fd, buffer, curlx_sztosi(len));
- length -= len;
- buffer += len;
- tx += len;
- }
- return tx;
-}
-
-/* Matches Curl_send signature */
-static ssize_t sec_send(struct connectdata *conn, int sockindex,
- const void *buffer, size_t len, CURLcode *err)
-{
- curl_socket_t fd = conn->sock[sockindex];
- *err = CURLE_OK;
- return sec_write(conn, fd, buffer, len);
-}
-
-int Curl_sec_read_msg(struct connectdata *conn, char *buffer,
- enum protection_level level)
-{
- /* decoded_len should be size_t or ssize_t but conn->mech->decode returns an
- int */
- int decoded_len;
- char *buf;
- int ret_code = 0;
- size_t decoded_sz = 0;
- CURLcode error;
-
- if(!conn->mech)
- /* not inititalized, return error */
- return -1;
-
- DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
-
- error = Curl_base64_decode(buffer + 4, (unsigned char **)&buf, &decoded_sz);
- if(error || decoded_sz == 0)
- return -1;
-
- if(decoded_sz > (size_t)INT_MAX) {
- free(buf);
- return -1;
- }
- decoded_len = curlx_uztosi(decoded_sz);
-
- decoded_len = conn->mech->decode(conn->app_data, buf, decoded_len,
- level, conn);
- if(decoded_len <= 0) {
- free(buf);
- return -1;
- }
-
- if(conn->data->set.verbose) {
- buf[decoded_len] = '\n';
- Curl_debug(conn->data, CURLINFO_HEADER_IN, buf, decoded_len + 1);
- }
-
- buf[decoded_len] = '\0';
- if(decoded_len <= 3)
- /* suspiciously short */
- return 0;
-
- if(buf[3] != '-')
- /* safe to ignore return code */
- (void)sscanf(buf, "%d", &ret_code);
-
- if(buf[decoded_len - 1] == '\n')
- buf[decoded_len - 1] = '\0';
- strcpy(buffer, buf);
- free(buf);
- return ret_code;
-}
-
-static int sec_set_protection_level(struct connectdata *conn)
-{
- int code;
- enum protection_level level = conn->request_data_prot;
-
- DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
-
- if(!conn->sec_complete) {
- infof(conn->data, "Trying to change the protection level after the"
- " completion of the data exchange.\n");
- return -1;
- }
-
- /* Bail out if we try to set up the same level */
- if(conn->data_prot == level)
- return 0;
-
- if(level) {
- char *pbsz;
- static unsigned int buffer_size = 1 << 20; /* 1048576 */
-
- code = ftp_send_command(conn, "PBSZ %u", buffer_size);
- if(code < 0)
- return -1;
-
- if(code/100 != 2) {
- failf(conn->data, "Failed to set the protection's buffer size.");
- return -1;
- }
- conn->buffer_size = buffer_size;
-
- pbsz = strstr(conn->data->state.buffer, "PBSZ=");
- if(pbsz) {
- /* ignore return code, use default value if it fails */
- (void)sscanf(pbsz, "PBSZ=%u", &buffer_size);
- if(buffer_size < conn->buffer_size)
- conn->buffer_size = buffer_size;
- }
- }
-
- /* Now try to negiociate the protection level. */
- code = ftp_send_command(conn, "PROT %c", level_to_char(level));
-
- if(code < 0)
- return -1;
-
- if(code/100 != 2) {
- failf(conn->data, "Failed to set the protection level.");
- return -1;
- }
-
- conn->data_prot = level;
- if(level == PROT_PRIVATE)
- conn->command_prot = level;
-
- return 0;
-}
-
-int
-Curl_sec_request_prot(struct connectdata *conn, const char *level)
-{
- enum protection_level l = name_to_level(level);
- if(l == PROT_NONE)
- return -1;
- DEBUGASSERT(l > PROT_NONE && l < PROT_LAST);
- conn->request_data_prot = l;
- return 0;
-}
-
-static CURLcode choose_mech(struct connectdata *conn)
-{
- int ret;
- struct Curl_easy *data = conn->data;
- void *tmp_allocation;
- const struct Curl_sec_client_mech *mech = &Curl_krb5_client_mech;
-
- tmp_allocation = realloc(conn->app_data, mech->size);
- if(tmp_allocation == NULL) {
- failf(data, "Failed realloc of size %zu", mech->size);
- mech = NULL;
- return CURLE_OUT_OF_MEMORY;
- }
- conn->app_data = tmp_allocation;
-
- if(mech->init) {
- ret = mech->init(conn->app_data);
- if(ret) {
- infof(data, "Failed initialization for %s. Skipping it.\n",
- mech->name);
- return CURLE_FAILED_INIT;
- }
- }
-
- infof(data, "Trying mechanism %s...\n", mech->name);
- ret = ftp_send_command(conn, "AUTH %s", mech->name);
- if(ret < 0)
- return CURLE_COULDNT_CONNECT;
-
- if(ret/100 != 3) {
- switch(ret) {
- case 504:
- infof(data, "Mechanism %s is not supported by the server (server "
- "returned ftp code: 504).\n", mech->name);
- break;
- case 534:
- infof(data, "Mechanism %s was rejected by the server (server returned "
- "ftp code: 534).\n", mech->name);
- break;
- default:
- if(ret/100 == 5) {
- infof(data, "server does not support the security extensions\n");
- return CURLE_USE_SSL_FAILED;
- }
- break;
- }
- return CURLE_LOGIN_DENIED;
- }
-
- /* Authenticate */
- ret = mech->auth(conn->app_data, conn);
-
- if(ret != AUTH_CONTINUE) {
- if(ret != AUTH_OK) {
- /* Mechanism has dumped the error to stderr, don't error here. */
- return -1;
- }
- DEBUGASSERT(ret == AUTH_OK);
-
- conn->mech = mech;
- conn->sec_complete = 1;
- conn->recv[FIRSTSOCKET] = sec_recv;
- conn->send[FIRSTSOCKET] = sec_send;
- conn->recv[SECONDARYSOCKET] = sec_recv;
- conn->send[SECONDARYSOCKET] = sec_send;
- conn->command_prot = PROT_SAFE;
- /* Set the requested protection level */
- /* BLOCKING */
- (void)sec_set_protection_level(conn);
- }
-
- return CURLE_OK;
-}
-
-CURLcode
-Curl_sec_login(struct connectdata *conn)
-{
- return choose_mech(conn);
-}
-
-
-void
-Curl_sec_end(struct connectdata *conn)
-{
- if(conn->mech != NULL && conn->mech->end)
- conn->mech->end(conn->app_data);
- free(conn->app_data);
- conn->app_data = NULL;
- if(conn->in_buffer.data) {
- free(conn->in_buffer.data);
- conn->in_buffer.data = NULL;
- conn->in_buffer.size = 0;
- conn->in_buffer.index = 0;
- conn->in_buffer.eof_flag = 0;
- }
- conn->sec_complete = 0;
- conn->data_prot = PROT_CLEAR;
- conn->mech = NULL;
-}
-
-#endif /* HAVE_GSSAPI */
-
-#endif /* CURL_DISABLE_FTP */
diff --git a/lib/select.c b/lib/select.c
index e2c97efe6..f38f3179a 100644
--- a/lib/select.c
+++ b/lib/select.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -149,15 +149,14 @@ int Curl_select(curl_socket_t maxfd, /* highest socket number */
{
struct timeval pending_tv;
struct timeval *ptimeout;
- int r;
#ifdef USE_WINSOCK
/* WinSock select() can't handle zero events. See the comment below. */
if((!fds_read || fds_read->fd_count == 0) &&
(!fds_write || fds_write->fd_count == 0) &&
(!fds_err || fds_err->fd_count == 0)) {
- r = Curl_wait_ms(timeout_ms);
- return r;
+ /* no sockets, just wait */
+ return Curl_wait_ms(timeout_ms);
}
#endif
@@ -209,17 +208,16 @@ int Curl_select(curl_socket_t maxfd, /* highest socket number */
descriptor set must contain at least one handle to a socket.
It is unclear why WinSock doesn't just handle this for us instead of
- calling this an error.
+ calling this an error. Luckily, with WinSock, we can _also_ ask how
+ many bits are set on an fd_set. So, let's just check it beforehand.
*/
- r = select((int)maxfd + 1,
- fds_read && fds_read->fd_count ? fds_read : NULL,
- fds_write && fds_write->fd_count ? fds_write : NULL,
- fds_err && fds_err->fd_count ? fds_err : NULL, ptimeout);
+ return select((int)maxfd + 1,
+ fds_read && fds_read->fd_count ? fds_read : NULL,
+ fds_write && fds_write->fd_count ? fds_write : NULL,
+ fds_err && fds_err->fd_count ? fds_err : NULL, ptimeout);
#else
- r = select((int)maxfd + 1, fds_read, fds_write, fds_err, ptimeout);
+ return select((int)maxfd + 1, fds_read, fds_write, fds_err, ptimeout);
#endif
-
- return r;
}
/*
@@ -247,23 +245,14 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
curl_socket_t writefd, /* socket to write to */
timediff_t timeout_ms) /* milliseconds to wait */
{
-#ifdef HAVE_POLL_FINE
struct pollfd pfd[3];
int num;
-#else
- fd_set fds_read;
- fd_set fds_write;
- fd_set fds_err;
- curl_socket_t maxfd;
-#endif
int r;
- int ret;
if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) &&
(writefd == CURL_SOCKET_BAD)) {
/* no sockets, just wait */
- r = Curl_wait_ms(timeout_ms);
- return r;
+ return Curl_wait_ms(timeout_ms);
}
/* Avoid initial timestamp, avoid Curl_now() call, when elapsed
@@ -271,8 +260,6 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
when function is called with a zero timeout or a negative timeout
value indicating a blocking call should be performed. */
-#ifdef HAVE_POLL_FINE
-
num = 0;
if(readfd0 != CURL_SOCKET_BAD) {
pfd[num].fd = readfd0;
@@ -288,7 +275,7 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
}
if(writefd != CURL_SOCKET_BAD) {
pfd[num].fd = writefd;
- pfd[num].events = POLLWRNORM|POLLOUT;
+ pfd[num].events = POLLWRNORM|POLLOUT|POLLPRI;
pfd[num].revents = 0;
num++;
}
@@ -297,101 +284,30 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
if(r <= 0)
return r;
- ret = 0;
+ r = 0;
num = 0;
if(readfd0 != CURL_SOCKET_BAD) {
if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
- ret |= CURL_CSELECT_IN;
+ r |= CURL_CSELECT_IN;
if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
- ret |= CURL_CSELECT_ERR;
+ r |= CURL_CSELECT_ERR;
num++;
}
if(readfd1 != CURL_SOCKET_BAD) {
if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
- ret |= CURL_CSELECT_IN2;
+ r |= CURL_CSELECT_IN2;
if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
- ret |= CURL_CSELECT_ERR;
+ r |= CURL_CSELECT_ERR;
num++;
}
if(writefd != CURL_SOCKET_BAD) {
if(pfd[num].revents & (POLLWRNORM|POLLOUT))
- ret |= CURL_CSELECT_OUT;
- if(pfd[num].revents & (POLLERR|POLLHUP|POLLNVAL))
- ret |= CURL_CSELECT_ERR;
- }
-
- return ret;
-
-#else /* HAVE_POLL_FINE */
-
- FD_ZERO(&fds_err);
- maxfd = (curl_socket_t)-1;
-
- FD_ZERO(&fds_read);
- if(readfd0 != CURL_SOCKET_BAD) {
- VERIFY_SOCK(readfd0);
- FD_SET(readfd0, &fds_read);
- FD_SET(readfd0, &fds_err);
- maxfd = readfd0;
- }
- if(readfd1 != CURL_SOCKET_BAD) {
- VERIFY_SOCK(readfd1);
- FD_SET(readfd1, &fds_read);
- FD_SET(readfd1, &fds_err);
- if(readfd1 > maxfd)
- maxfd = readfd1;
- }
-
- FD_ZERO(&fds_write);
- if(writefd != CURL_SOCKET_BAD) {
- VERIFY_SOCK(writefd);
- FD_SET(writefd, &fds_write);
- FD_SET(writefd, &fds_err);
- if(writefd > maxfd)
- maxfd = writefd;
- }
-
- /* We know that we have at least one bit set in at least two fd_sets in
- this case, but we may have no bits set in either fds_read or fd_write,
- so check for that and handle it. Luckily, with WinSock, we can _also_
- ask how many bits are set on an fd_set.
-
- Note also that WinSock ignores the first argument, so we don't worry
- about the fact that maxfd is computed incorrectly with WinSock (since
- curl_socket_t is unsigned in such cases and thus -1 is the largest
- value).
- */
- r = Curl_select(maxfd, &fds_read, &fds_write, &fds_err, timeout_ms);
-
- if(r < 0)
- return -1;
- if(r == 0)
- return 0;
-
- ret = 0;
- if(readfd0 != CURL_SOCKET_BAD) {
- if(FD_ISSET(readfd0, &fds_read))
- ret |= CURL_CSELECT_IN;
- if(FD_ISSET(readfd0, &fds_err))
- ret |= CURL_CSELECT_ERR;
- }
- if(readfd1 != CURL_SOCKET_BAD) {
- if(FD_ISSET(readfd1, &fds_read))
- ret |= CURL_CSELECT_IN2;
- if(FD_ISSET(readfd1, &fds_err))
- ret |= CURL_CSELECT_ERR;
- }
- if(writefd != CURL_SOCKET_BAD) {
- if(FD_ISSET(writefd, &fds_write))
- ret |= CURL_CSELECT_OUT;
- if(FD_ISSET(writefd, &fds_err))
- ret |= CURL_CSELECT_ERR;
+ r |= CURL_CSELECT_OUT;
+ if(pfd[num].revents & (POLLERR|POLLHUP|POLLPRI|POLLNVAL))
+ r |= CURL_CSELECT_ERR;
}
- return ret;
-
-#endif /* HAVE_POLL_FINE */
-
+ return r;
}
/*
@@ -431,8 +347,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
}
if(fds_none) {
/* no sockets, just wait */
- r = Curl_wait_ms(timeout_ms);
- return r;
+ return Curl_wait_ms(timeout_ms);
}
/* Avoid initial timestamp, avoid Curl_now() call, when elapsed
@@ -454,11 +369,8 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
else
pending_ms = 0;
r = poll(ufds, nfds, pending_ms);
-
- if(r < 0)
- return -1;
- if(r == 0)
- return 0;
+ if(r <= 0)
+ return r;
for(i = 0; i < nfds; i++) {
if(ufds[i].fd == CURL_SOCKET_BAD)
@@ -466,7 +378,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
if(ufds[i].revents & POLLHUP)
ufds[i].revents |= POLLIN;
if(ufds[i].revents & POLLERR)
- ufds[i].revents |= (POLLIN|POLLOUT);
+ ufds[i].revents |= POLLIN|POLLOUT;
}
#else /* HAVE_POLL_FINE */
@@ -482,7 +394,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
continue;
VERIFY_SOCK(ufds[i].fd);
if(ufds[i].events & (POLLIN|POLLOUT|POLLPRI|
- POLLRDNORM|POLLWRNORM|POLLRDBAND)) {
+ POLLRDNORM|POLLWRNORM|POLLRDBAND)) {
if(ufds[i].fd > maxfd)
maxfd = ufds[i].fd;
if(ufds[i].events & (POLLRDNORM|POLLIN))
@@ -494,24 +406,39 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
}
}
+ /*
+ Note also that WinSock ignores the first argument, so we don't worry
+ about the fact that maxfd is computed incorrectly with WinSock (since
+ curl_socket_t is unsigned in such cases and thus -1 is the largest
+ value).
+ */
r = Curl_select(maxfd, &fds_read, &fds_write, &fds_err, timeout_ms);
-
- if(r < 0)
- return -1;
- if(r == 0)
- return 0;
+ if(r <= 0)
+ return r;
r = 0;
for(i = 0; i < nfds; i++) {
ufds[i].revents = 0;
if(ufds[i].fd == CURL_SOCKET_BAD)
continue;
- if(FD_ISSET(ufds[i].fd, &fds_read))
- ufds[i].revents |= POLLIN;
- if(FD_ISSET(ufds[i].fd, &fds_write))
- ufds[i].revents |= POLLOUT;
- if(FD_ISSET(ufds[i].fd, &fds_err))
- ufds[i].revents |= POLLPRI;
+ if(FD_ISSET(ufds[i].fd, &fds_read)) {
+ if(ufds[i].events & POLLRDNORM)
+ ufds[i].revents |= POLLRDNORM;
+ if(ufds[i].events & POLLIN)
+ ufds[i].revents |= POLLIN;
+ }
+ if(FD_ISSET(ufds[i].fd, &fds_write)) {
+ if(ufds[i].events & POLLWRNORM)
+ ufds[i].revents |= POLLWRNORM;
+ if(ufds[i].events & POLLOUT)
+ ufds[i].revents |= POLLOUT;
+ }
+ if(FD_ISSET(ufds[i].fd, &fds_err)) {
+ if(ufds[i].events & POLLRDBAND)
+ ufds[i].revents |= POLLRDBAND;
+ if(ufds[i].events & POLLPRI)
+ ufds[i].revents |= POLLPRI;
+ }
if(ufds[i].revents != 0)
r++;
}
diff --git a/lib/select.h b/lib/select.h
index 95181f467..135095043 100644
--- a/lib/select.h
+++ b/lib/select.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -94,12 +94,23 @@ int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
fd_set* excepts, struct timeval *tv);
#endif
-/* Winsock and TPF sockets are not in range [0..FD_SETSIZE-1], which
+/* TPF sockets are not in range [0..FD_SETSIZE-1], which
unfortunately makes it impossible for us to easily check if they're valid
+
+ With Winsock the valid range is [0..INVALID_SOCKET-1] according to
+ https://docs.microsoft.com/en-us/windows/win32/winsock/socket-data-type-2
*/
-#if defined(USE_WINSOCK) || defined(TPF)
+#if defined(TPF)
#define VALID_SOCK(x) 1
#define VERIFY_SOCK(x) Curl_nop_stmt
+#elif defined(USE_WINSOCK)
+#define VALID_SOCK(s) ((s) < INVALID_SOCKET)
+#define VERIFY_SOCK(x) do { \
+ if(!VALID_SOCK(x)) { \
+ SET_SOCKERRNO(WSAEINVAL); \
+ return -1; \
+ } \
+} while(0)
#else
#define VALID_SOCK(s) (((s) >= 0) && ((s) < FD_SETSIZE))
#define VERIFY_SOCK(x) do { \
diff --git a/lib/sendf.c b/lib/sendf.c
index 8ac46db0c..aefbe7bfe 100644
--- a/lib/sendf.c
+++ b/lib/sendf.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -28,6 +28,8 @@
#ifdef HAVE_LINUX_TCP_H
#include <linux/tcp.h>
+#elif defined(HAVE_NETINET_TCP_H)
+#include <netinet/tcp.h>
#endif
#include <gnurl/curl.h>
@@ -140,7 +142,7 @@ bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex)
psnd->recv_size > psnd->recv_processed;
}
-static void pre_receive_plain(struct connectdata *conn, int num)
+static CURLcode pre_receive_plain(struct connectdata *conn, int num)
{
const curl_socket_t sockfd = conn->sock[num];
struct postponed_data * const psnd = &(conn->postponed[num]);
@@ -161,6 +163,8 @@ static void pre_receive_plain(struct connectdata *conn, int num)
/* Use buffer double default size for intermediate buffer */
psnd->allocated_size = 2 * conn->data->set.buffer_size;
psnd->buffer = malloc(psnd->allocated_size);
+ if(!psnd->buffer)
+ return CURLE_OUT_OF_MEMORY;
psnd->recv_size = 0;
psnd->recv_processed = 0;
#ifdef DEBUGBUILD
@@ -180,6 +184,7 @@ static void pre_receive_plain(struct connectdata *conn, int num)
psnd->allocated_size = 0;
}
}
+ return CURLE_OK;
}
static ssize_t get_pre_recved(struct connectdata *conn, int num, char *buf,
@@ -225,7 +230,7 @@ bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex)
(void)sockindex;
return false;
}
-#define pre_receive_plain(c,n) do {} while(0)
+#define pre_receive_plain(c,n) CURLE_OK
#define get_pre_recved(c,n,b,l) 0
#endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
@@ -274,61 +279,12 @@ void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
strcpy(data->set.errorbuffer, error);
data->state.errorbuf = TRUE; /* wrote error string */
}
- if(data->set.verbose) {
- error[len] = '\n';
- error[++len] = '\0';
- Curl_debug(data, CURLINFO_TEXT, error, len);
- }
+ error[len++] = '\n';
+ Curl_debug(data, CURLINFO_TEXT, error, len);
va_end(ap);
}
}
-/* Curl_sendf() sends formatted data to the server */
-CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
- const char *fmt, ...)
-{
- struct Curl_easy *data = conn->data;
- ssize_t bytes_written;
- size_t write_len;
- CURLcode result = CURLE_OK;
- char *s;
- char *sptr;
- va_list ap;
- va_start(ap, fmt);
- s = vaprintf(fmt, ap); /* returns an allocated string */
- va_end(ap);
- if(!s)
- return CURLE_OUT_OF_MEMORY; /* failure */
-
- bytes_written = 0;
- write_len = strlen(s);
- sptr = s;
-
- for(;;) {
- /* Write the buffer to the socket */
- result = Curl_write(conn, sockfd, sptr, write_len, &bytes_written);
-
- if(result)
- break;
-
- if(data->set.verbose)
- Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written);
-
- if((size_t)bytes_written != write_len) {
- /* if not all was written at once, we must advance the pointer, decrease
- the size left and try again! */
- write_len -= bytes_written;
- sptr += bytes_written;
- }
- else
- break;
- }
-
- free(s); /* free the output string */
-
- return result;
-}
-
/*
* Curl_write() is an internal write function that sends data to the
* server. Works with plain sockets, SCP, SSL or kerberos.
@@ -379,7 +335,10 @@ ssize_t Curl_send_plain(struct connectdata *conn, int num,
To avoid lossage of received data, recv() must be
performed before every send() if any incoming data is
available. */
- pre_receive_plain(conn, num);
+ if(pre_receive_plain(conn, num)) {
+ *code = CURLE_OUT_OF_MEMORY;
+ return -1;
+ }
#if defined(MSG_FASTOPEN) && !defined(TCP_FASTOPEN_CONNECT) /* Linux */
if(conn->bits.tcp_fastopen) {
@@ -733,72 +692,74 @@ CURLcode Curl_read(struct connectdata *conn, /* connection data */
int Curl_debug(struct Curl_easy *data, curl_infotype type,
char *ptr, size_t size)
{
- static const char s_infotype[CURLINFO_END][3] = {
- "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
int rc = 0;
+ if(data->set.verbose) {
+ static const char s_infotype[CURLINFO_END][3] = {
+ "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
#ifdef CURL_DOES_CONVERSIONS
- char *buf = NULL;
- size_t conv_size = 0;
-
- switch(type) {
- case CURLINFO_HEADER_OUT:
- buf = Curl_memdup(ptr, size);
- if(!buf)
- return 1;
- conv_size = size;
-
- /* Special processing is needed for this block if it
- * contains both headers and data (separated by CRLFCRLF).
- * We want to convert just the headers, leaving the data as-is.
- */
- if(size > 4) {
- size_t i;
- for(i = 0; i < size-4; i++) {
- if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) {
- /* convert everything through this CRLFCRLF but no further */
- conv_size = i + 4;
- break;
+ char *buf = NULL;
+ size_t conv_size = 0;
+
+ switch(type) {
+ case CURLINFO_HEADER_OUT:
+ buf = Curl_memdup(ptr, size);
+ if(!buf)
+ return 1;
+ conv_size = size;
+
+ /* Special processing is needed for this block if it
+ * contains both headers and data (separated by CRLFCRLF).
+ * We want to convert just the headers, leaving the data as-is.
+ */
+ if(size > 4) {
+ size_t i;
+ for(i = 0; i < size-4; i++) {
+ if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) {
+ /* convert everything through this CRLFCRLF but no further */
+ conv_size = i + 4;
+ break;
+ }
}
}
- }
- Curl_convert_from_network(data, buf, conv_size);
- /* Curl_convert_from_network calls failf if unsuccessful */
- /* we might as well continue even if it fails... */
- ptr = buf; /* switch pointer to use my buffer instead */
- break;
- default:
- /* leave everything else as-is */
- break;
- }
+ Curl_convert_from_network(data, buf, conv_size);
+ /* Curl_convert_from_network calls failf if unsuccessful */
+ /* we might as well continue even if it fails... */
+ ptr = buf; /* switch pointer to use my buffer instead */
+ break;
+ default:
+ /* leave everything else as-is */
+ break;
+ }
#endif /* CURL_DOES_CONVERSIONS */
- if(data->set.fdebug) {
- Curl_set_in_callback(data, true);
- rc = (*data->set.fdebug)(data, type, ptr, size, data->set.debugdata);
- Curl_set_in_callback(data, false);
- }
- else {
- switch(type) {
- case CURLINFO_TEXT:
- case CURLINFO_HEADER_OUT:
- case CURLINFO_HEADER_IN:
- fwrite(s_infotype[type], 2, 1, data->set.err);
- fwrite(ptr, size, 1, data->set.err);
+ if(data->set.fdebug) {
+ Curl_set_in_callback(data, true);
+ rc = (*data->set.fdebug)(data, type, ptr, size, data->set.debugdata);
+ Curl_set_in_callback(data, false);
+ }
+ else {
+ switch(type) {
+ case CURLINFO_TEXT:
+ case CURLINFO_HEADER_OUT:
+ case CURLINFO_HEADER_IN:
+ fwrite(s_infotype[type], 2, 1, data->set.err);
+ fwrite(ptr, size, 1, data->set.err);
#ifdef CURL_DOES_CONVERSIONS
- if(size != conv_size) {
- /* we had untranslated data so we need an explicit newline */
- fwrite("\n", 1, 1, data->set.err);
- }
+ if(size != conv_size) {
+ /* we had untranslated data so we need an explicit newline */
+ fwrite("\n", 1, 1, data->set.err);
+ }
#endif
- break;
- default: /* nada */
- break;
+ break;
+ default: /* nada */
+ break;
+ }
}
- }
#ifdef CURL_DOES_CONVERSIONS
- free(buf);
+ free(buf);
#endif
+ }
return rc;
}
diff --git a/lib/sendf.h b/lib/sendf.h
index c68b017da..c7e67c745 100644
--- a/lib/sendf.h
+++ b/lib/sendf.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -24,8 +24,6 @@
#include "curl_setup.h"
-CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *,
- const char *fmt, ...);
void Curl_infof(struct Curl_easy *, const char *fmt, ...);
void Curl_failf(struct Curl_easy *, const char *fmt, ...);
diff --git a/lib/setopt.c b/lib/setopt.c
index c044de3c3..0105a26bc 100644
--- a/lib/setopt.c
+++ b/lib/setopt.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -30,6 +30,8 @@
#ifdef HAVE_LINUX_TCP_H
#include <linux/tcp.h>
+#elif defined(HAVE_NETINET_TCP_H)
+#include <netinet/tcp.h>
#endif
#include "urldata.h"
@@ -45,6 +47,7 @@
#include "setopt.h"
#include "multiif.h"
#include "altsvc.h"
+#include "hsts.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -430,104 +433,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
primary->version_max = version_max;
}
#else
- result = CURLE_UNKNOWN_OPTION;
+ result = CURLE_NOT_BUILT_IN;
#endif
break;
-#ifndef CURL_DISABLE_HTTP
- case CURLOPT_AUTOREFERER:
- /*
- * Switch on automatic referer that gets set if curl follows locations.
- */
- data->set.http_auto_referer = (0 != va_arg(param, long)) ? TRUE : FALSE;
- break;
-
- case CURLOPT_ACCEPT_ENCODING:
- /*
- * String to use at the value of Accept-Encoding header.
- *
- * If the encoding is set to "" we use an Accept-Encoding header that
- * encompasses all the encodings we support.
- * If the encoding is set to NULL we don't send an Accept-Encoding header
- * and ignore an received Content-Encoding header.
- *
- */
- argptr = va_arg(param, char *);
- if(argptr && !*argptr) {
- argptr = Curl_all_content_encodings();
- if(!argptr)
- result = CURLE_OUT_OF_MEMORY;
- else {
- result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr);
- free(argptr);
- }
- }
- else
- result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr);
- break;
-
- case CURLOPT_TRANSFER_ENCODING:
- data->set.http_transfer_encoding = (0 != va_arg(param, long)) ?
- TRUE : FALSE;
- break;
-
- case CURLOPT_FOLLOWLOCATION:
- /*
- * Follow Location: header hints on a HTTP-server.
- */
- data->set.http_follow_location = (0 != va_arg(param, long)) ? TRUE : FALSE;
- break;
-
- case CURLOPT_UNRESTRICTED_AUTH:
- /*
- * Send authentication (user+password) when following locations, even when
- * hostname changed.
- */
- data->set.allow_auth_to_other_hosts =
- (0 != va_arg(param, long)) ? TRUE : FALSE;
- break;
-
- case CURLOPT_MAXREDIRS:
- /*
- * The maximum amount of hops you allow curl to follow Location:
- * headers. This should mostly be used to detect never-ending loops.
- */
- arg = va_arg(param, long);
- if(arg < -1)
- return CURLE_BAD_FUNCTION_ARGUMENT;
- data->set.maxredirs = arg;
- break;
-
- case CURLOPT_POSTREDIR:
- /*
- * Set the behaviour of POST when redirecting
- * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302
- * CURL_REDIR_POST_301 - POST is kept as POST after 301
- * CURL_REDIR_POST_302 - POST is kept as POST after 302
- * CURL_REDIR_POST_303 - POST is kept as POST after 303
- * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303
- * other - POST is kept as POST after 301 and 302
- */
- arg = va_arg(param, long);
- if(arg < CURL_REDIR_GET_ALL)
- /* no return error on too high numbers since the bitmask could be
- extended in a future */
- return CURLE_BAD_FUNCTION_ARGUMENT;
- data->set.keep_post = arg & CURL_REDIR_POST_ALL;
- break;
-
- case CURLOPT_POST:
- /* Does this option serve a purpose anymore? Yes it does, when
- CURLOPT_POSTFIELDS isn't used and the POST data is read off the
- callback! */
- if(va_arg(param, long)) {
- data->set.method = HTTPREQ_POST;
- data->set.opt_no_body = FALSE; /* this is implied */
- }
- else
- data->set.method = HTTPREQ_GET;
- break;
-
+ /* MQTT "borrows" some of the HTTP options */
+#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_MQTT)
case CURLOPT_COPYPOSTFIELDS:
/*
* A string with POST data. Makes curl HTTP POST. Even if it is NULL.
@@ -622,6 +533,100 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
data->set.postfieldsize = bigsize;
break;
+#endif
+#ifndef CURL_DISABLE_HTTP
+ case CURLOPT_AUTOREFERER:
+ /*
+ * Switch on automatic referer that gets set if curl follows locations.
+ */
+ data->set.http_auto_referer = (0 != va_arg(param, long)) ? TRUE : FALSE;
+ break;
+
+ case CURLOPT_ACCEPT_ENCODING:
+ /*
+ * String to use at the value of Accept-Encoding header.
+ *
+ * If the encoding is set to "" we use an Accept-Encoding header that
+ * encompasses all the encodings we support.
+ * If the encoding is set to NULL we don't send an Accept-Encoding header
+ * and ignore an received Content-Encoding header.
+ *
+ */
+ argptr = va_arg(param, char *);
+ if(argptr && !*argptr) {
+ argptr = Curl_all_content_encodings();
+ if(!argptr)
+ result = CURLE_OUT_OF_MEMORY;
+ else {
+ result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr);
+ free(argptr);
+ }
+ }
+ else
+ result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr);
+ break;
+
+ case CURLOPT_TRANSFER_ENCODING:
+ data->set.http_transfer_encoding = (0 != va_arg(param, long)) ?
+ TRUE : FALSE;
+ break;
+
+ case CURLOPT_FOLLOWLOCATION:
+ /*
+ * Follow Location: header hints on a HTTP-server.
+ */
+ data->set.http_follow_location = (0 != va_arg(param, long)) ? TRUE : FALSE;
+ break;
+
+ case CURLOPT_UNRESTRICTED_AUTH:
+ /*
+ * Send authentication (user+password) when following locations, even when
+ * hostname changed.
+ */
+ data->set.allow_auth_to_other_hosts =
+ (0 != va_arg(param, long)) ? TRUE : FALSE;
+ break;
+
+ case CURLOPT_MAXREDIRS:
+ /*
+ * The maximum amount of hops you allow curl to follow Location:
+ * headers. This should mostly be used to detect never-ending loops.
+ */
+ arg = va_arg(param, long);
+ if(arg < -1)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.maxredirs = arg;
+ break;
+
+ case CURLOPT_POSTREDIR:
+ /*
+ * Set the behaviour of POST when redirecting
+ * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302
+ * CURL_REDIR_POST_301 - POST is kept as POST after 301
+ * CURL_REDIR_POST_302 - POST is kept as POST after 302
+ * CURL_REDIR_POST_303 - POST is kept as POST after 303
+ * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303
+ * other - POST is kept as POST after 301 and 302
+ */
+ arg = va_arg(param, long);
+ if(arg < CURL_REDIR_GET_ALL)
+ /* no return error on too high numbers since the bitmask could be
+ extended in a future */
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ data->set.keep_post = arg & CURL_REDIR_POST_ALL;
+ break;
+
+ case CURLOPT_POST:
+ /* Does this option serve a purpose anymore? Yes it does, when
+ CURLOPT_POSTFIELDS isn't used and the POST data is read off the
+ callback! */
+ if(va_arg(param, long)) {
+ data->set.method = HTTPREQ_POST;
+ data->set.opt_no_body = FALSE; /* this is implied */
+ }
+ else
+ data->set.method = HTTPREQ_GET;
+ break;
case CURLOPT_HTTPPOST:
/*
@@ -720,6 +725,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
argptr = (char *)va_arg(param, void *);
if(argptr) {
struct curl_slist *cl;
+ /* general protection against mistakes and abuse */
+ if(strlen(argptr) > CURL_MAX_INPUT_LENGTH)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
/* append the cookie file name to the list of file names, and deal with
them later */
cl = curl_slist_append(data->change.cookielist, argptr);
@@ -804,6 +812,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
/* if cookie engine was not running, activate it */
data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE);
+ /* general protection against mistakes and abuse */
+ if(strlen(argptr) > CURL_MAX_INPUT_LENGTH)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
argptr = strdup(argptr);
if(!argptr || !data->cookies) {
result = CURLE_OUT_OF_MEMORY;
@@ -1069,7 +1080,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
break;
default:
/* reserve other values for future use */
- result = CURLE_UNKNOWN_OPTION;
+ result = CURLE_BAD_FUNCTION_ARGUMENT;
break;
}
break;
@@ -1222,21 +1233,13 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
* An FTP/SFTP option that modifies an upload to create missing
* directories on the server.
*/
- switch(va_arg(param, long)) {
- case 0:
- data->set.ftp_create_missing_dirs = 0;
- break;
- case 1:
- data->set.ftp_create_missing_dirs = 1;
- break;
- case 2:
- data->set.ftp_create_missing_dirs = 2;
- break;
- default:
- /* reserve other values for future use */
- result = CURLE_UNKNOWN_OPTION;
- break;
- }
+ arg = va_arg(param, long);
+ /* reserve other values for future use */
+ if((arg < CURLFTP_CREATE_DIR_NONE) ||
+ (arg > CURLFTP_CREATE_DIR_RETRY))
+ result = CURLE_BAD_FUNCTION_ARGUMENT;
+ else
+ data->set.ftp_create_missing_dirs = (int)arg;
break;
case CURLOPT_READDATA:
/*
@@ -2075,6 +2078,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
* The application kindly asks for a differently sized receive buffer.
* If it seems reasonable, we'll use it.
*/
+ if(data->state.buffer)
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+
arg = va_arg(param, long);
if(arg > READBUFFER_MAX)
@@ -2084,18 +2090,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
else if(arg < READBUFFER_MIN)
arg = READBUFFER_MIN;
- /* Resize if new size */
- if((arg != data->set.buffer_size) && data->state.buffer) {
- char *newbuff = realloc(data->state.buffer, arg + 1);
- if(!newbuff) {
- DEBUGF(fprintf(stderr, "Error: realloc of buffer failed\n"));
- result = CURLE_OUT_OF_MEMORY;
- }
- else
- data->state.buffer = newbuff;
- }
data->set.buffer_size = arg;
-
break;
case CURLOPT_UPLOAD_BUFFERSIZE:
@@ -2243,6 +2238,14 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
break;
#endif
+ case CURLOPT_SSL_EC_CURVES:
+ /*
+ * Set accepted curves in SSL connection setup.
+ * Specify colon-delimited list of curve algorithm names.
+ */
+ result = Curl_setstropt(&data->set.str[STRING_SSL_EC_CURVES],
+ va_arg(param, char *));
+ break;
#endif
case CURLOPT_IPRESOLVE:
arg = va_arg(param, long);
@@ -2513,9 +2516,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
* Set the RTSP request method (OPTIONS, SETUP, PLAY, etc...)
* Would this be better if the RTSPREQ_* were just moved into here?
*/
- long curl_rtspreq = va_arg(param, long);
+ long in_rtspreq = va_arg(param, long);
Curl_RtspReq rtspreq = RTSPREQ_NONE;
- switch(curl_rtspreq) {
+ switch(in_rtspreq) {
case CURL_RTSPREQ_OPTIONS:
rtspreq = RTSPREQ_OPTIONS;
break;
@@ -2839,7 +2842,46 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
data->set.trailer_data = va_arg(param, void *);
#endif
break;
-#ifdef USE_ALTSVC
+#ifdef USE_HSTS
+ case CURLOPT_HSTSREADFUNCTION:
+ data->set.hsts_read = va_arg(param, curl_hstsread_callback);
+ break;
+ case CURLOPT_HSTSREADDATA:
+ data->set.hsts_read_userp = va_arg(param, void *);
+ break;
+ case CURLOPT_HSTSWRITEFUNCTION:
+ data->set.hsts_write = va_arg(param, curl_hstswrite_callback);
+ break;
+ case CURLOPT_HSTSWRITEDATA:
+ data->set.hsts_write_userp = va_arg(param, void *);
+ break;
+ case CURLOPT_HSTS:
+ if(!data->hsts) {
+ data->hsts = Curl_hsts_init();
+ if(!data->hsts)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ argptr = va_arg(param, char *);
+ result = Curl_setstropt(&data->set.str[STRING_HSTS], argptr);
+ if(result)
+ return result;
+ if(argptr)
+ (void)Curl_hsts_loadfile(data, data->hsts, argptr);
+ break;
+ case CURLOPT_HSTS_CTRL:
+ arg = va_arg(param, long);
+ if(arg & CURLHSTS_ENABLE) {
+ if(!data->hsts) {
+ data->hsts = Curl_hsts_init();
+ if(!data->hsts)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ }
+ else
+ Curl_hsts_cleanup(&data->hsts);
+ break;
+#endif
+#ifndef CURL_DISABLE_ALTSVC
case CURLOPT_ALTSVC:
if(!data->asi) {
data->asi = Curl_altsvc_init();
diff --git a/lib/setopt.h b/lib/setopt.h
index 5fc4368dc..affbfd996 100644
--- a/lib/setopt.h
+++ b/lib/setopt.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/setup-os400.h b/lib/setup-os400.h
index b693cb3b3..8c97371e4 100644
--- a/lib/setup-os400.h
+++ b/lib/setup-os400.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/setup-vms.h b/lib/setup-vms.h
index 0e39c9f6b..ba75dc295 100644
--- a/lib/setup-vms.h
+++ b/lib/setup-vms.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/setup-win32.h b/lib/setup-win32.h
index 45b584766..c35dec88c 100644
--- a/lib/setup-win32.h
+++ b/lib/setup-win32.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -60,7 +60,6 @@
/*
* Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else
- * define USE_WINSOCK to 1 if we have and use WINSOCK API, else
* undefine USE_WINSOCK.
*/
@@ -70,7 +69,7 @@
# define USE_WINSOCK 2
#else
# ifdef HAVE_WINSOCK_H
-# define USE_WINSOCK 1
+# error "WinSock version 1 is no longer supported, version 2 is required!"
# endif
#endif
diff --git a/lib/sha256.c b/lib/sha256.c
index ee5d273c4..910d7ae1e 100644
--- a/lib/sha256.c
+++ b/lib/sha256.c
@@ -10,7 +10,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/share.c b/lib/share.c
index 70c6e025f..12c2993fe 100644
--- a/lib/share.c
+++ b/lib/share.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -92,7 +92,7 @@ curl_share_setopt(struct Curl_share *share, CURLSHoption option, ...)
if(!share->sslsession) {
share->max_ssl_sessions = 8;
share->sslsession = calloc(share->max_ssl_sessions,
- sizeof(struct curl_ssl_session));
+ sizeof(struct Curl_ssl_session));
share->sessionage = 0;
if(!share->sslsession)
res = CURLSHE_NOMEM;
diff --git a/lib/share.h b/lib/share.h
index da3bf1765..86ec8bb5d 100644
--- a/lib/share.h
+++ b/lib/share.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -46,7 +46,7 @@ struct Curl_share {
curl_unlock_function unlockfunc;
void *clientdata;
struct conncache conn_cache;
- struct curl_hash hostcache;
+ struct Curl_hash hostcache;
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
struct CookieInfo *cookies;
#endif
@@ -54,7 +54,7 @@ struct Curl_share {
struct PslCache psl;
#endif
- struct curl_ssl_session *sslsession;
+ struct Curl_ssl_session *sslsession;
size_t max_ssl_sessions;
long sessionage;
};
diff --git a/lib/sigpipe.h b/lib/sigpipe.h
index 3960a139d..430cfc648 100644
--- a/lib/sigpipe.h
+++ b/lib/sigpipe.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/slist.c b/lib/slist.c
index b59eda449..20c46b6d4 100644
--- a/lib/slist.c
+++ b/lib/slist.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/slist.h b/lib/slist.h
index 799b3c060..3114259cf 100644
--- a/lib/slist.h
+++ b/lib/slist.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/smb.c b/lib/smb.c
index d493adcc0..dd914a05b 100644
--- a/lib/smb.c
+++ b/lib/smb.c
@@ -10,7 +10,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -23,11 +23,9 @@
#include "curl_setup.h"
-#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
+#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \
(CURL_SIZEOF_CURL_OFF_T > 4)
-#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
-
#define BUILDING_CURL_SMB_C
#ifdef HAVE_PROCESS_H
@@ -88,6 +86,7 @@ const struct Curl_handler Curl_handler_smb = {
ZERO_NULL, /* connection_check */
PORT_SMB, /* defport */
CURLPROTO_SMB, /* protocol */
+ CURLPROTO_SMB, /* family */
PROTOPT_NONE /* flags */
};
@@ -113,6 +112,7 @@ const struct Curl_handler Curl_handler_smbs = {
ZERO_NULL, /* connection_check */
PORT_SMBS, /* defport */
CURLPROTO_SMBS, /* protocol */
+ CURLPROTO_SMB, /* family */
PROTOPT_SSL /* flags */
};
#endif
@@ -204,7 +204,7 @@ static void conn_state(struct connectdata *conn, enum smb_conn_state newstate)
static void request_state(struct connectdata *conn,
enum smb_req_state newstate)
{
- struct smb_request *req = conn->data->req.protop;
+ struct smb_request *req = conn->data->req.p.smb;
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
/* For debug purposes */
static const char * const names[] = {
@@ -234,7 +234,7 @@ static CURLcode smb_setup_connection(struct connectdata *conn)
struct smb_request *req;
/* Initialize the request state */
- conn->data->req.protop = req = calloc(1, sizeof(struct smb_request));
+ conn->data->req.p.smb = req = calloc(1, sizeof(struct smb_request));
if(!req)
return CURLE_OUT_OF_MEMORY;
@@ -342,7 +342,7 @@ static void smb_format_message(struct connectdata *conn, struct smb_header *h,
unsigned char cmd, size_t len)
{
struct smb_conn *smbc = &conn->proto.smbc;
- struct smb_request *req = conn->data->req.protop;
+ struct smb_request *req = conn->data->req.p.smb;
unsigned int pid;
memset(h, 0, sizeof(*h));
@@ -505,7 +505,7 @@ static CURLcode smb_send_tree_connect(struct connectdata *conn)
static CURLcode smb_send_open(struct connectdata *conn)
{
- struct smb_request *req = conn->data->req.protop;
+ struct smb_request *req = conn->data->req.p.smb;
struct smb_nt_create msg;
size_t byte_count;
@@ -535,7 +535,7 @@ static CURLcode smb_send_open(struct connectdata *conn)
static CURLcode smb_send_close(struct connectdata *conn)
{
- struct smb_request *req = conn->data->req.protop;
+ struct smb_request *req = conn->data->req.p.smb;
struct smb_close msg;
memset(&msg, 0, sizeof(msg));
@@ -556,7 +556,7 @@ static CURLcode smb_send_tree_disconnect(struct connectdata *conn)
static CURLcode smb_send_read(struct connectdata *conn)
{
- struct smb_request *req = conn->data->req.protop;
+ struct smb_request *req = conn->data->req.p.smb;
curl_off_t offset = conn->data->req.offset;
struct smb_read msg;
@@ -575,7 +575,7 @@ static CURLcode smb_send_read(struct connectdata *conn)
static CURLcode smb_send_write(struct connectdata *conn)
{
struct smb_write *msg;
- struct smb_request *req = conn->data->req.protop;
+ struct smb_request *req = conn->data->req.p.smb;
curl_off_t offset = conn->data->req.offset;
curl_off_t upload_size = conn->data->req.size - conn->data->req.bytecount;
CURLcode result = Curl_get_upload_buffer(conn->data);
@@ -738,7 +738,7 @@ static void get_posix_time(time_t *out, curl_off_t timestamp)
static CURLcode smb_request_state(struct connectdata *conn, bool *done)
{
- struct smb_request *req = conn->data->req.protop;
+ struct smb_request *req = conn->data->req.p.smb;
struct smb_header *h;
struct smb_conn *smbc = &conn->proto.smbc;
enum smb_req_state next_state = SMB_DONE;
@@ -923,7 +923,7 @@ static CURLcode smb_done(struct connectdata *conn, CURLcode status,
bool premature)
{
(void) premature;
- Curl_safefree(conn->data->req.protop);
+ Curl_safefree(conn->data->req.p.smb);
return status;
}
@@ -957,7 +957,7 @@ static CURLcode smb_do(struct connectdata *conn, bool *done)
static CURLcode smb_parse_url_path(struct connectdata *conn)
{
struct Curl_easy *data = conn->data;
- struct smb_request *req = data->req.protop;
+ struct smb_request *req = data->req.p.smb;
struct smb_conn *smbc = &conn->proto.smbc;
char *path;
char *slash;
@@ -996,6 +996,5 @@ static CURLcode smb_parse_url_path(struct connectdata *conn)
return CURLE_OK;
}
-#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
-
-#endif /* CURL_DISABLE_SMB && USE_NTLM && CURL_SIZEOF_CURL_OFF_T > 4 */
+#endif /* CURL_DISABLE_SMB && USE_CURL_NTLM_CORE &&
+ CURL_SIZEOF_CURL_OFF_T > 4 */
diff --git a/lib/smb.h b/lib/smb.h
index 136a89ce9..907cf0c8e 100644
--- a/lib/smb.h
+++ b/lib/smb.h
@@ -12,7 +12,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -243,16 +243,13 @@ struct smb_tree_disconnect {
#endif /* BUILDING_CURL_SMB_C */
-#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
+#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \
(CURL_SIZEOF_CURL_OFF_T > 4)
-#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
-
extern const struct Curl_handler Curl_handler_smb;
extern const struct Curl_handler Curl_handler_smbs;
-#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
-
-#endif /* CURL_DISABLE_SMB && USE_NTLM && CURL_SIZEOF_CURL_OFF_T > 4 */
+#endif /* CURL_DISABLE_SMB && USE_CURL_NTLM_CORE &&
+ CURL_SIZEOF_CURL_OFF_T > 4 */
#endif /* HEADER_CURL_SMB_H */
diff --git a/lib/smtp.c b/lib/smtp.c
index 7d8ef8406..2bd8c1a19 100644
--- a/lib/smtp.c
+++ b/lib/smtp.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -133,6 +133,7 @@ const struct Curl_handler Curl_handler_smtp = {
ZERO_NULL, /* connection_check */
PORT_SMTP, /* defport */
CURLPROTO_SMTP, /* protocol */
+ CURLPROTO_SMTP, /* family */
PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
PROTOPT_URLOPTIONS
};
@@ -160,6 +161,7 @@ const struct Curl_handler Curl_handler_smtps = {
ZERO_NULL, /* connection_check */
PORT_SMTPS, /* defport */
CURLPROTO_SMTPS, /* protocol */
+ CURLPROTO_SMTP, /* family */
PROTOPT_CLOSEACTION | PROTOPT_SSL
| PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS /* flags */
};
@@ -484,7 +486,7 @@ static CURLcode smtp_perform_command(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct SMTP *smtp = data->req.protop;
+ struct SMTP *smtp = data->req.p.smtp;
if(smtp->rcpt) {
/* We notify the server we are sending UTF-8 data if a) it supports the
@@ -697,7 +699,7 @@ static CURLcode smtp_perform_mail(struct connectdata *conn)
any there do, as we need to correctly identify our support for SMTPUTF8
in the envelope, as per RFC-6531 sect. 3.4 */
if(conn->proto.smtpc.utf8_supported && !utf8) {
- struct SMTP *smtp = data->req.protop;
+ struct SMTP *smtp = data->req.p.smtp;
struct curl_slist *rcpt = smtp->rcpt;
while(rcpt && !utf8) {
@@ -741,7 +743,7 @@ static CURLcode smtp_perform_rcpt_to(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct SMTP *smtp = data->req.protop;
+ struct SMTP *smtp = data->req.p.smtp;
char *address = NULL;
struct hostname host = { NULL, NULL, NULL, NULL };
@@ -989,7 +991,7 @@ static CURLcode smtp_state_command_resp(struct connectdata *conn, int smtpcode,
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct SMTP *smtp = data->req.protop;
+ struct SMTP *smtp = data->req.p.smtp;
char *line = data->state.buffer;
size_t len = strlen(line);
@@ -1055,7 +1057,7 @@ static CURLcode smtp_state_rcpt_resp(struct connectdata *conn, int smtpcode,
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct SMTP *smtp = data->req.protop;
+ struct SMTP *smtp = data->req.p.smtp;
bool is_smtp_err = FALSE;
bool is_smtp_blocking_err = FALSE;
@@ -1278,7 +1280,7 @@ static CURLcode smtp_init(struct connectdata *conn)
struct Curl_easy *data = conn->data;
struct SMTP *smtp;
- smtp = data->req.protop = calloc(sizeof(struct SMTP), 1);
+ smtp = data->req.p.smtp = calloc(sizeof(struct SMTP), 1);
if(!smtp)
result = CURLE_OUT_OF_MEMORY;
@@ -1322,6 +1324,7 @@ static CURLcode smtp_connect(struct connectdata *conn, bool *done)
Curl_sasl_init(&smtpc->sasl, &saslsmtp);
/* Initialise the pingpong layer */
+ Curl_pp_setup(pp);
Curl_pp_init(pp);
/* Parse the URL options */
@@ -1356,7 +1359,7 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct SMTP *smtp = data->req.protop;
+ struct SMTP *smtp = data->req.p.smtp;
struct pingpong *pp = &conn->proto.smtpc.pp;
char *eob;
ssize_t len;
@@ -1442,7 +1445,7 @@ static CURLcode smtp_perform(struct connectdata *conn, bool *connected,
/* This is SMTP and no proxy */
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct SMTP *smtp = data->req.protop;
+ struct SMTP *smtp = data->req.p.smtp;
DEBUGF(infof(conn->data, "DO phase starts\n"));
@@ -1550,7 +1553,7 @@ static CURLcode smtp_disconnect(struct connectdata *conn, bool dead_connection)
/* Call this when the DO phase has completed */
static CURLcode smtp_dophase_done(struct connectdata *conn, bool connected)
{
- struct SMTP *smtp = conn->data->req.protop;
+ struct SMTP *smtp = conn->data->req.p.smtp;
(void)connected;
@@ -1703,7 +1706,7 @@ static CURLcode smtp_parse_custom_request(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct SMTP *smtp = data->req.protop;
+ struct SMTP *smtp = data->req.p.smtp;
const char *custom = data->set.str[STRING_CUSTOMREQUEST];
/* URL decode the custom request */
@@ -1796,7 +1799,7 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread)
ssize_t i;
ssize_t si;
struct Curl_easy *data = conn->data;
- struct SMTP *smtp = data->req.protop;
+ struct SMTP *smtp = data->req.p.smtp;
char *scratch = data->state.scratch;
char *newscratch = NULL;
char *oldscratch = NULL;
diff --git a/lib/smtp.h b/lib/smtp.h
index 164a175d7..c7c62ee85 100644
--- a/lib/smtp.h
+++ b/lib/smtp.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/sockaddr.h b/lib/sockaddr.h
index b037ee06c..84c08d9bb 100644
--- a/lib/sockaddr.h
+++ b/lib/sockaddr.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/socketpair.c b/lib/socketpair.c
index 1ec0d75a4..2c580ad2d 100644
--- a/lib/socketpair.c
+++ b/lib/socketpair.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -23,7 +23,7 @@
#include "curl_setup.h"
#include "socketpair.h"
-#ifndef HAVE_SOCKETPAIR
+#if !defined(HAVE_SOCKETPAIR) && !defined(CURL_DISABLE_SOCKETPAIR)
#ifdef WIN32
/*
* This is a socketpair() implementation for Windows.
diff --git a/lib/socketpair.h b/lib/socketpair.h
index be9fb24f9..033a235aa 100644
--- a/lib/socketpair.h
+++ b/lib/socketpair.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/socks.c b/lib/socks.c
index 44783d015..a2d1e621f 100644
--- a/lib/socks.c
+++ b/lib/socks.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -184,12 +184,12 @@ int Curl_SOCKS_getsock(struct connectdata *conn, curl_socket_t *sock,
* Set protocol4a=true for "SOCKS 4A (Simple Extension to SOCKS 4 Protocol)"
* Nonsupport "Identification Protocol (RFC1413)"
*/
-CURLcode Curl_SOCKS4(const char *proxy_user,
- const char *hostname,
- int remote_port,
- int sockindex,
- struct connectdata *conn,
- bool *done)
+CURLproxycode Curl_SOCKS4(const char *proxy_user,
+ const char *hostname,
+ int remote_port,
+ int sockindex,
+ struct connectdata *conn,
+ bool *done)
{
const bool protocol4a =
(conn->socks_proxy.proxytype == CURLPROXY_SOCKS4A) ? TRUE : FALSE;
@@ -237,11 +237,11 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
Curl_resolv(conn, hostname, remote_port, FALSE, &dns);
if(rc == CURLRESOLV_ERROR)
- return CURLE_COULDNT_RESOLVE_PROXY;
+ return CURLPX_RESOLVE_HOST;
else if(rc == CURLRESOLV_PENDING) {
sxstate(conn, CONNECT_RESOLVING);
infof(data, "SOCKS4 non-blocking resolve of %s\n", hostname);
- return CURLE_OK;
+ return CURLPX_OK;
}
sxstate(conn, CONNECT_RESOLVED);
goto CONNECT_RESOLVED;
@@ -265,8 +265,11 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
}
else {
result = Curl_resolv_check(data->conn, &dns);
- if(!dns)
- return result;
+ if(!dns) {
+ if(result)
+ return CURLPX_RESOLVE_HOST;
+ return CURLPX_OK;
+ }
}
/* FALLTHROUGH */
CONNECT_RESOLVED:
@@ -303,7 +306,7 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
if(!hp) {
failf(data, "Failed to resolve \"%s\" for SOCKS4 connect.",
hostname);
- return CURLE_COULDNT_RESOLVE_HOST;
+ return CURLPX_RESOLVE_HOST;
}
}
/* FALLTHROUGH */
@@ -316,8 +319,8 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
if(proxy_user) {
size_t plen = strlen(proxy_user);
if(plen >= sizeof(sx->socksreq) - 8) {
- failf(data, "Too long SOCKS proxy name, can't use!\n");
- return CURLE_COULDNT_CONNECT;
+ failf(data, "Too long SOCKS proxy user name, can't use!\n");
+ return CURLPX_LONG_USER;
}
/* copy the proxy name WITH trailing zero */
memcpy(socksreq + 8, proxy_user, plen + 1);
@@ -343,7 +346,7 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
strcpy((char *)socksreq + packetsize, hostname);
else {
failf(data, "SOCKS4: too long host name");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_LONG_HOSTNAME;
}
packetsize += hostnamelen;
}
@@ -358,13 +361,13 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
sx->outstanding, &written);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Failed to send SOCKS4 connect request.");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_SEND_CONNECT;
}
if(written != sx->outstanding) {
/* not done, remain in state */
sx->outstanding -= written;
sx->outp += written;
- return CURLE_OK;
+ return CURLPX_OK;
}
/* done sending! */
@@ -380,18 +383,18 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
if(result && (CURLE_AGAIN != result)) {
failf(data, "SOCKS4: Failed receiving connect request ack: %s",
curl_easy_strerror(result));
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_RECV_CONNECT;
}
else if(!result && !actualread) {
/* connection closed */
failf(data, "connection to proxy closed");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_CLOSED;
}
else if(actualread != sx->outstanding) {
/* remain in reading state */
sx->outstanding -= actualread;
sx->outp += actualread;
- return CURLE_OK;
+ return CURLPX_OK;
}
sxstate(conn, CONNECT_DONE);
break;
@@ -422,7 +425,7 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
if(socksreq[0] != 0) {
failf(data,
"SOCKS4 reply has wrong version, version should be 0.");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_BAD_VERSION;
}
/* Result */
@@ -438,7 +441,7 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
(unsigned char)socksreq[6], (unsigned char)socksreq[7],
(((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
(unsigned char)socksreq[1]);
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_REQUEST_FAILED;
case 92:
failf(data,
"Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
@@ -448,7 +451,7 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
(unsigned char)socksreq[6], (unsigned char)socksreq[7],
(((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
(unsigned char)socksreq[1]);
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_IDENTD;
case 93:
failf(data,
"Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
@@ -458,7 +461,7 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
(unsigned char)socksreq[6], (unsigned char)socksreq[7],
(((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
(unsigned char)socksreq[1]);
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_IDENTD_DIFFER;
default:
failf(data,
"Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
@@ -467,24 +470,24 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
(unsigned char)socksreq[6], (unsigned char)socksreq[7],
(((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
(unsigned char)socksreq[1]);
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_UNKNOWN_FAIL;
}
*done = TRUE;
- return CURLE_OK; /* Proxy was successful! */
+ return CURLPX_OK; /* Proxy was successful! */
}
/*
* This function logs in to a SOCKS5 proxy and sends the specifics to the final
* destination server.
*/
-CURLcode Curl_SOCKS5(const char *proxy_user,
- const char *proxy_password,
- const char *hostname,
- int remote_port,
- int sockindex,
- struct connectdata *conn,
- bool *done)
+CURLproxycode Curl_SOCKS5(const char *proxy_user,
+ const char *proxy_password,
+ const char *hostname,
+ int remote_port,
+ int sockindex,
+ struct connectdata *conn,
+ bool *done)
{
/*
According to the RFC1928, section "6. Replies". This is what a SOCK5
@@ -561,13 +564,13 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
result = Curl_write_plain(conn, sockfd, (char *)socksreq, idx, &written);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Unable to send initial SOCKS5 request.");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_SEND_CONNECT;
}
if(written != idx) {
sxstate(conn, CONNECT_SOCKS_SEND);
sx->outstanding = idx - written;
sx->outp = &socksreq[written];
- return CURLE_OK;
+ return CURLPX_OK;
}
sxstate(conn, CONNECT_SOCKS_READ);
goto CONNECT_SOCKS_READ_INIT;
@@ -576,13 +579,13 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
sx->outstanding, &written);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Unable to send initial SOCKS5 request.");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_SEND_CONNECT;
}
if(written != sx->outstanding) {
/* not done, remain in state */
sx->outstanding -= written;
sx->outp += written;
- return CURLE_OK;
+ return CURLPX_OK;
}
/* FALLTHROUGH */
CONNECT_SOCKS_READ_INIT:
@@ -595,22 +598,22 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
sx->outstanding, &actualread);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Unable to receive initial SOCKS5 response.");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_RECV_CONNECT;
}
else if(!result && !actualread) {
/* connection closed */
failf(data, "Connection to proxy closed");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_CLOSED;
}
else if(actualread != sx->outstanding) {
/* remain in reading state */
sx->outstanding -= actualread;
sx->outp += actualread;
- return CURLE_OK;
+ return CURLPX_OK;
}
else if(socksreq[0] != 5) {
failf(data, "Received invalid version in initial SOCKS5 response.");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_BAD_VERSION;
}
else if(socksreq[1] == 0) {
/* DONE! No authentication needed. Send request. */
@@ -628,7 +631,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
result = Curl_SOCKS5_gssapi_negotiate(sockindex, conn);
if(result) {
failf(data, "Unable to negotiate SOCKS5 GSS-API context.");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_GSSAPI;
}
}
#endif
@@ -637,16 +640,16 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
if(!allow_gssapi && (socksreq[1] == 1)) {
failf(data,
"SOCKS5 GSSAPI per-message authentication is not supported.");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_GSSAPI_PERMSG;
}
else if(socksreq[1] == 255) {
failf(data, "No authentication method was acceptable.");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_NO_AUTH;
}
}
failf(data,
"Undocumented SOCKS5 mode attempted to be used by server.");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_UNKNOWN_MODE;
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
case CONNECT_GSSAPI_INIT:
/* GSSAPI stuff done non-blocking */
@@ -683,7 +686,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
/* the length must fit in a single byte */
if(proxy_user_len >= 255) {
failf(data, "Excessive user name length for proxy auth");
- return CURLE_BAD_FUNCTION_ARGUMENT;
+ return CURLPX_LONG_USER;
}
memcpy(socksreq + len, proxy_user, proxy_user_len);
}
@@ -693,7 +696,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
/* the length must fit in a single byte */
if(proxy_password_len > 255) {
failf(data, "Excessive password length for proxy auth");
- return CURLE_BAD_FUNCTION_ARGUMENT;
+ return CURLPX_LONG_PASSWD;
}
memcpy(socksreq + len, proxy_password, proxy_password_len);
}
@@ -708,13 +711,13 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
sx->outstanding, &written);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Failed to send SOCKS5 sub-negotiation request.");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_SEND_AUTH;
}
if(sx->outstanding != written) {
/* remain in state */
sx->outstanding -= written;
sx->outp += written;
- return CURLE_OK;
+ return CURLPX_OK;
}
sx->outp = socksreq;
sx->outstanding = 2;
@@ -725,24 +728,24 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
sx->outstanding, &actualread);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Unable to receive SOCKS5 sub-negotiation response.");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_RECV_AUTH;
}
else if(!result && !actualread) {
/* connection closed */
failf(data, "connection to proxy closed");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_CLOSED;
}
else if(actualread != sx->outstanding) {
/* remain in state */
sx->outstanding -= actualread;
sx->outp += actualread;
- return CURLE_OK;
+ return CURLPX_OK;
}
/* ignore the first (VER) byte */
else if(socksreq[1] != 0) { /* status */
failf(data, "User was rejected by the SOCKS5 server (%d %d).",
socksreq[0], socksreq[1]);
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_USER_REJECTED;
}
/* Everything is good so far, user was authenticated! */
@@ -755,11 +758,11 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
FALSE, &dns);
if(rc == CURLRESOLV_ERROR)
- return CURLE_COULDNT_RESOLVE_HOST;
+ return CURLPX_RESOLVE_HOST;
if(rc == CURLRESOLV_PENDING) {
sxstate(conn, CONNECT_RESOLVING);
- return CURLE_OK;
+ return CURLPX_OK;
}
sxstate(conn, CONNECT_RESOLVED);
goto CONNECT_RESOLVED;
@@ -768,7 +771,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
case CONNECT_RESOLVING:
/* check if we have the name resolved by now */
- dns = Curl_fetch_addr(conn, hostname, (int)conn->port);
+ dns = Curl_fetch_addr(conn, hostname, remote_port);
if(dns) {
#ifdef CURLRES_ASYNCH
@@ -780,8 +783,11 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
if(!dns) {
result = Curl_resolv_check(data->conn, &dns);
- if(!dns)
- return result;
+ if(!dns) {
+ if(result)
+ return CURLPX_RESOLVE_HOST;
+ return CURLPX_OK;
+ }
}
/* FALLTHROUGH */
CONNECT_RESOLVED:
@@ -793,7 +799,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
if(!hp) {
failf(data, "Failed to resolve \"%s\" for SOCKS5 connect.",
hostname);
- return CURLE_COULDNT_RESOLVE_HOST;
+ return CURLPX_RESOLVE_HOST;
}
Curl_printable_address(hp, dest, sizeof(dest));
@@ -867,7 +873,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
if(conn->socks5_gssapi_enctype) {
failf(data, "SOCKS5 GSS-API protection not yet implemented.");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_GSSAPI_PROTECTION;
}
#endif
sx->outp = socksreq;
@@ -879,18 +885,18 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
sx->outstanding, &written);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Failed to send SOCKS5 connect request.");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_SEND_REQUEST;
}
if(sx->outstanding != written) {
/* remain in state */
sx->outstanding -= written;
sx->outp += written;
- return CURLE_OK;
+ return CURLPX_OK;
}
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
if(conn->socks5_gssapi_enctype) {
failf(data, "SOCKS5 GSS-API protection not yet implemented.");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_GSSAPI_PROTECTION;
}
#endif
sx->outstanding = 10; /* minimum packet size is 10 */
@@ -902,29 +908,46 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
sx->outstanding, &actualread);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Failed to receive SOCKS5 connect request ack.");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_RECV_REQACK;
}
else if(!result && !actualread) {
/* connection closed */
failf(data, "connection to proxy closed");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_CLOSED;
}
else if(actualread != sx->outstanding) {
/* remain in state */
sx->outstanding -= actualread;
sx->outp += actualread;
- return CURLE_OK;
+ return CURLPX_OK;
}
if(socksreq[0] != 5) { /* version */
failf(data,
"SOCKS5 reply has wrong version, version should be 5.");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_BAD_VERSION;
}
else if(socksreq[1] != 0) { /* Anything besides 0 is an error */
+ CURLproxycode rc = CURLPX_REPLY_UNASSIGNED;
+ int code = socksreq[1];
failf(data, "Can't complete SOCKS5 connection to %s. (%d)",
hostname, (unsigned char)socksreq[1]);
- return CURLE_COULDNT_CONNECT;
+ if(code < 9) {
+ /* RFC 1928 section 6 lists: */
+ static const CURLproxycode lookup[] = {
+ CURLPX_OK,
+ CURLPX_REPLY_GENERAL_SERVER_FAILURE,
+ CURLPX_REPLY_NOT_ALLOWED,
+ CURLPX_REPLY_NETWORK_UNREACHABLE,
+ CURLPX_REPLY_HOST_UNREACHABLE,
+ CURLPX_REPLY_CONNECTION_REFUSED,
+ CURLPX_REPLY_TTL_EXPIRED,
+ CURLPX_REPLY_COMMAND_NOT_SUPPORTED,
+ CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED,
+ };
+ rc = lookup[code];
+ }
+ return rc;
}
/* Fix: in general, returned BND.ADDR is variable length parameter by RFC
@@ -958,7 +981,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
}
else {
failf(data, "SOCKS5 reply has wrong address type.");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_BAD_ADDRESS_TYPE;
}
/* At this point we already read first 10 bytes */
@@ -984,25 +1007,25 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
sx->outstanding, &actualread);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Failed to receive SOCKS5 connect request ack.");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_RECV_ADDRESS;
}
else if(!result && !actualread) {
/* connection closed */
failf(data, "connection to proxy closed");
- return CURLE_COULDNT_CONNECT;
+ return CURLPX_CLOSED;
}
else if(actualread != sx->outstanding) {
/* remain in state */
sx->outstanding -= actualread;
sx->outp += actualread;
- return CURLE_OK;
+ return CURLPX_OK;
}
sxstate(conn, CONNECT_DONE);
}
infof(data, "SOCKS5 request granted.\n");
*done = TRUE;
- return CURLE_OK; /* Proxy was successful! */
+ return CURLPX_OK; /* Proxy was successful! */
}
#endif /* CURL_DISABLE_PROXY */
diff --git a/lib/socks.h b/lib/socks.h
index 64a756337..1fae58b6f 100644
--- a/lib/socks.h
+++ b/lib/socks.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -48,24 +48,24 @@ int Curl_SOCKS_getsock(struct connectdata *conn,
* This function logs in to a SOCKS4(a) proxy and sends the specifics to the
* final destination server.
*/
-CURLcode Curl_SOCKS4(const char *proxy_name,
- const char *hostname,
- int remote_port,
- int sockindex,
- struct connectdata *conn,
- bool *done);
+CURLproxycode Curl_SOCKS4(const char *proxy_name,
+ const char *hostname,
+ int remote_port,
+ int sockindex,
+ struct connectdata *conn,
+ bool *done);
/*
* This function logs in to a SOCKS5 proxy and sends the specifics to the
* final destination server.
*/
-CURLcode Curl_SOCKS5(const char *proxy_name,
- const char *proxy_password,
- const char *hostname,
- int remote_port,
- int sockindex,
- struct connectdata *conn,
- bool *done);
+CURLproxycode Curl_SOCKS5(const char *proxy_name,
+ const char *proxy_password,
+ const char *hostname,
+ int remote_port,
+ int sockindex,
+ struct connectdata *conn,
+ bool *done);
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
/*
diff --git a/lib/socks_gssapi.c b/lib/socks_gssapi.c
index 2e36b9940..a96579692 100644
--- a/lib/socks_gssapi.c
+++ b/lib/socks_gssapi.c
@@ -10,7 +10,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -493,7 +493,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
gss_release_buffer(&gss_status, &gss_recv_token);
if(gss_w_token.length != 1) {
- failf(data, "Invalid GSS-API encryption response length (%d).",
+ failf(data, "Invalid GSS-API encryption response length (%zu).",
gss_w_token.length);
gss_release_buffer(&gss_status, &gss_w_token);
gss_delete_sec_context(&gss_status, &gss_context, NULL);
@@ -505,7 +505,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
}
else {
if(gss_recv_token.length != 1) {
- failf(data, "Invalid GSS-API encryption response length (%d).",
+ failf(data, "Invalid GSS-API encryption response length (%zu).",
gss_recv_token.length);
gss_release_buffer(&gss_status, &gss_recv_token);
gss_delete_sec_context(&gss_status, &gss_context, NULL);
diff --git a/lib/socks_sspi.c b/lib/socks_sspi.c
index 2f1fd36fa..b9ac2ade8 100644
--- a/lib/socks_sspi.c
+++ b/lib/socks_sspi.c
@@ -10,7 +10,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/speedcheck.c b/lib/speedcheck.c
index 86920a078..0c56cf135 100644
--- a/lib/speedcheck.c
+++ b/lib/speedcheck.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/speedcheck.h b/lib/speedcheck.h
index 5c2dc9a22..1d4c7bfef 100644
--- a/lib/speedcheck.h
+++ b/lib/speedcheck.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/splay.c b/lib/splay.c
index 0f5fcd1e8..98baf5d87 100644
--- a/lib/splay.c
+++ b/lib/splay.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1997 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1997 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -206,9 +206,9 @@ struct Curl_tree *Curl_splaygetbest(struct curltime i,
*
* @unittest: 1309
*/
-int Curl_splayremovebyaddr(struct Curl_tree *t,
- struct Curl_tree *removenode,
- struct Curl_tree **newroot)
+int Curl_splayremove(struct Curl_tree *t,
+ struct Curl_tree *removenode,
+ struct Curl_tree **newroot)
{
static const struct curltime KEY_NOTUSED = {
(time_t)-1, (unsigned int)-1
diff --git a/lib/splay.h b/lib/splay.h
index 9292f349b..eb9f65f1e 100644
--- a/lib/splay.h
+++ b/lib/splay.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1997 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1997 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -40,19 +40,13 @@ struct Curl_tree *Curl_splayinsert(struct curltime key,
struct Curl_tree *t,
struct Curl_tree *newnode);
-#if 0
-struct Curl_tree *Curl_splayremove(struct curltime key,
- struct Curl_tree *t,
- struct Curl_tree **removed);
-#endif
-
struct Curl_tree *Curl_splaygetbest(struct curltime key,
struct Curl_tree *t,
struct Curl_tree **removed);
-int Curl_splayremovebyaddr(struct Curl_tree *t,
- struct Curl_tree *removenode,
- struct Curl_tree **newroot);
+int Curl_splayremove(struct Curl_tree *t,
+ struct Curl_tree *removenode,
+ struct Curl_tree **newroot);
#define Curl_splaycomparekeys(i,j) ( ((i.tv_sec) < (j.tv_sec)) ? -1 : \
( ((i.tv_sec) > (j.tv_sec)) ? 1 : \
diff --git a/lib/strcase.c b/lib/strcase.c
index 1c2d104aa..b117e2366 100644
--- a/lib/strcase.c
+++ b/lib/strcase.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/strcase.h b/lib/strcase.h
index 6e9e3e0b2..eec7aa1e3 100644
--- a/lib/strcase.h
+++ b/lib/strcase.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/strdup.c b/lib/strdup.c
index 8444357a7..edc399e01 100644
--- a/lib/strdup.c
+++ b/lib/strdup.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/strdup.h b/lib/strdup.h
index ae3d5d011..0936956f8 100644
--- a/lib/strdup.h
+++ b/lib/strdup.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/strerror.c b/lib/strerror.c
index f9f5a8415..589dd7574 100644
--- a/lib/strerror.c
+++ b/lib/strerror.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -320,6 +320,9 @@ curl_easy_strerror(CURLcode error)
case CURLE_QUIC_CONNECT_ERROR:
return "QUIC connection error";
+ case CURLE_PROXY:
+ return "proxy handshake error";
+
/* error codes not used by current libcurl */
case CURLE_OBSOLETE20:
case CURLE_OBSOLETE24:
@@ -652,34 +655,27 @@ static const char *
get_winapi_error(int err, char *buf, size_t buflen)
{
char *p;
+ wchar_t wbuf[256];
if(!buflen)
return NULL;
*buf = '\0';
-
-#ifdef _WIN32_WCE
- {
- wchar_t wbuf[256];
- wbuf[0] = L'\0';
-
- if(FormatMessage((FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err,
- LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) {
- size_t written = wcstombs(buf, wbuf, buflen - 1);
- if(written != (size_t)-1)
- buf[written] = '\0';
- else
- *buf = '\0';
- }
- }
-#else
- if(!FormatMessageA((FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err,
- LANG_NEUTRAL, buf, (DWORD)buflen, NULL)) {
- *buf = '\0';
+ *wbuf = L'\0';
+
+ /* We return the local codepage version of the error string because if it is
+ output to the user's terminal it will likely be with functions which
+ expect the local codepage (eg fprintf, failf, infof).
+ FormatMessageW -> wcstombs is used for Windows CE compatibility. */
+ if(FormatMessageW((FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err,
+ LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) {
+ size_t written = wcstombs(buf, wbuf, buflen - 1);
+ if(written != (size_t)-1)
+ buf[written] = '\0';
+ else
+ *buf = '\0';
}
-#endif
/* Truncate multiple lines */
p = strchr(buf, '\n');
@@ -785,7 +781,7 @@ const char *Curl_strerror(int err, char *buf, size_t buflen)
}
#else
{
- char *msg = strerror(err);
+ const char *msg = strerror(err);
if(msg)
strncpy(buf, msg, max);
else
diff --git a/lib/strerror.h b/lib/strerror.h
index bae8f8974..96a7e27c5 100644
--- a/lib/strerror.h
+++ b/lib/strerror.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/strtok.c b/lib/strtok.c
index ba6e0258a..d53e587ab 100644
--- a/lib/strtok.c
+++ b/lib/strtok.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/strtok.h b/lib/strtok.h
index e221fa680..831ef0c00 100644
--- a/lib/strtok.h
+++ b/lib/strtok.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/strtoofft.c b/lib/strtoofft.c
index 96e382060..ac87cfc5b 100644
--- a/lib/strtoofft.c
+++ b/lib/strtoofft.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/strtoofft.h b/lib/strtoofft.h
index be19cd716..4d22ba36c 100644
--- a/lib/strtoofft.h
+++ b/lib/strtoofft.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/system_win32.c b/lib/system_win32.c
index 55a6ebfeb..3d6c9d4a1 100644
--- a/lib/system_win32.c
+++ b/lib/system_win32.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -55,12 +55,7 @@ CURLcode Curl_win32_init(long flags)
WSADATA wsaData;
int res;
-#if defined(ENABLE_IPV6) && (USE_WINSOCK < 2)
-#error IPV6_requires_winsock2
-#endif
-
- wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
-
+ wVersionRequested = MAKEWORD(2, 2);
res = WSAStartup(wVersionRequested, &wsaData);
if(res != 0)
@@ -83,9 +78,9 @@ CURLcode Curl_win32_init(long flags)
return CURLE_FAILED_INIT;
}
/* The Windows Sockets DLL is acceptable. Proceed. */
- #elif defined(USE_LWIPSOCK)
+#elif defined(USE_LWIPSOCK)
lwip_init();
- #endif
+#endif
} /* CURL_GLOBAL_WIN32 */
#ifdef USE_WINDOWS_SSPI
diff --git a/lib/system_win32.h b/lib/system_win32.h
index 2547bda95..69e0c812c 100644
--- a/lib/system_win32.h
+++ b/lib/system_win32.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/telnet.c b/lib/telnet.c
index e43f5dd1e..fa232b795 100644
--- a/lib/telnet.c
+++ b/lib/telnet.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -87,12 +87,6 @@
#define printoption(a,b,c,d) Curl_nop_stmt
#endif
-#ifdef USE_WINSOCK
-typedef WSAEVENT (WINAPI *WSOCK2_EVENT)(void);
-typedef FARPROC WSOCK2_FUNC;
-static CURLcode check_wsock2(struct Curl_easy *data);
-#endif
-
static
CURLcode telrcv(struct connectdata *,
const unsigned char *inbuf, /* Data received from socket */
@@ -194,50 +188,11 @@ const struct Curl_handler Curl_handler_telnet = {
ZERO_NULL, /* connection_check */
PORT_TELNET, /* defport */
CURLPROTO_TELNET, /* protocol */
+ CURLPROTO_TELNET, /* family */
PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */
};
-#ifdef USE_WINSOCK
-static CURLcode
-check_wsock2(struct Curl_easy *data)
-{
- int err;
- WORD wVersionRequested;
- WSADATA wsaData;
-
- DEBUGASSERT(data);
-
- /* telnet requires at least WinSock 2.0 so ask for it. */
- wVersionRequested = MAKEWORD(2, 0);
-
- err = WSAStartup(wVersionRequested, &wsaData);
-
- /* We must've called this once already, so this call */
- /* should always succeed. But, just in case... */
- if(err != 0) {
- failf(data,"WSAStartup failed (%d)",err);
- return CURLE_FAILED_INIT;
- }
-
- /* We have to have a WSACleanup call for every successful */
- /* WSAStartup call. */
- WSACleanup();
-
- /* Check that our version is supported */
- if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
- HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested)) {
- /* Our version isn't supported */
- failf(data, "insufficient winsock version to support "
- "telnet");
- return CURLE_FAILED_INIT;
- }
-
- /* Our version is supported */
- return CURLE_OK;
-}
-#endif
-
static
CURLcode init_telnet(struct connectdata *conn)
{
@@ -247,7 +202,7 @@ CURLcode init_telnet(struct connectdata *conn)
if(!tn)
return CURLE_OUT_OF_MEMORY;
- conn->data->req.protop = tn; /* make us known */
+ conn->data->req.p.telnet = tn; /* make us known */
tn->telrcv_state = CURL_TS_DATA;
@@ -292,7 +247,7 @@ CURLcode init_telnet(struct connectdata *conn)
static void negotiate(struct connectdata *conn)
{
int i;
- struct TELNET *tn = (struct TELNET *) conn->data->req.protop;
+ struct TELNET *tn = (struct TELNET *) conn->data->req.p.telnet;
for(i = 0; i < CURL_NTELOPTS; i++) {
if(i == CURL_TELOPT_ECHO)
@@ -365,7 +320,7 @@ static void send_negotiation(struct connectdata *conn, int cmd, int option)
static
void set_remote_option(struct connectdata *conn, int option, int newstate)
{
- struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+ struct TELNET *tn = (struct TELNET *)conn->data->req.p.telnet;
if(newstate == CURL_YES) {
switch(tn->him[option]) {
case CURL_NO:
@@ -439,7 +394,7 @@ void set_remote_option(struct connectdata *conn, int option, int newstate)
static
void rec_will(struct connectdata *conn, int option)
{
- struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+ struct TELNET *tn = (struct TELNET *)conn->data->req.p.telnet;
switch(tn->him[option]) {
case CURL_NO:
if(tn->him_preferred[option] == CURL_YES) {
@@ -487,7 +442,7 @@ void rec_will(struct connectdata *conn, int option)
static
void rec_wont(struct connectdata *conn, int option)
{
- struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+ struct TELNET *tn = (struct TELNET *)conn->data->req.p.telnet;
switch(tn->him[option]) {
case CURL_NO:
/* Already disabled */
@@ -529,7 +484,7 @@ void rec_wont(struct connectdata *conn, int option)
static void
set_local_option(struct connectdata *conn, int option, int newstate)
{
- struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+ struct TELNET *tn = (struct TELNET *)conn->data->req.p.telnet;
if(newstate == CURL_YES) {
switch(tn->us[option]) {
case CURL_NO:
@@ -603,7 +558,7 @@ set_local_option(struct connectdata *conn, int option, int newstate)
static
void rec_do(struct connectdata *conn, int option)
{
- struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+ struct TELNET *tn = (struct TELNET *)conn->data->req.p.telnet;
switch(tn->us[option]) {
case CURL_NO:
if(tn->us_preferred[option] == CURL_YES) {
@@ -663,7 +618,7 @@ void rec_do(struct connectdata *conn, int option)
static
void rec_dont(struct connectdata *conn, int option)
{
- struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+ struct TELNET *tn = (struct TELNET *)conn->data->req.p.telnet;
switch(tn->us[option]) {
case CURL_NO:
/* Already disabled */
@@ -822,7 +777,7 @@ static CURLcode check_telnet_options(struct connectdata *conn)
char option_keyword[128] = "";
char option_arg[256] = "";
struct Curl_easy *data = conn->data;
- struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+ struct TELNET *tn = (struct TELNET *)conn->data->req.p.telnet;
CURLcode result = CURLE_OK;
int binary_option;
@@ -929,7 +884,7 @@ static void suboption(struct connectdata *conn)
char varname[128] = "";
char varval[128] = "";
struct Curl_easy *data = conn->data;
- struct TELNET *tn = (struct TELNET *)data->req.protop;
+ struct TELNET *tn = (struct TELNET *)data->req.p.telnet;
printsub(data, '<', (unsigned char *)tn->subbuffer, CURL_SB_LEN(tn) + 2);
switch(CURL_SB_GET(tn)) {
@@ -1004,7 +959,7 @@ static void sendsuboption(struct connectdata *conn, int option)
unsigned char *uc1, *uc2;
struct Curl_easy *data = conn->data;
- struct TELNET *tn = (struct TELNET *)data->req.protop;
+ struct TELNET *tn = (struct TELNET *)data->req.p.telnet;
switch(option) {
case CURL_TELOPT_NAWS:
@@ -1062,7 +1017,7 @@ CURLcode telrcv(struct connectdata *conn,
int in = 0;
int startwrite = -1;
struct Curl_easy *data = conn->data;
- struct TELNET *tn = (struct TELNET *)data->req.protop;
+ struct TELNET *tn = (struct TELNET *)data->req.p.telnet;
#define startskipping() \
if(startwrite >= 0) { \
@@ -1280,7 +1235,7 @@ static CURLcode send_telnet_data(struct connectdata *conn,
static CURLcode telnet_done(struct connectdata *conn,
CURLcode status, bool premature)
{
- struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+ struct TELNET *tn = (struct TELNET *)conn->data->req.p.telnet;
(void)status; /* unused */
(void)premature; /* not used */
@@ -1290,7 +1245,7 @@ static CURLcode telnet_done(struct connectdata *conn,
curl_slist_free_all(tn->telnet_vars);
tn->telnet_vars = NULL;
- Curl_safefree(conn->data->req.protop);
+ Curl_safefree(conn->data->req.p.telnet);
return CURLE_OK;
}
@@ -1301,11 +1256,6 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
struct Curl_easy *data = conn->data;
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
#ifdef USE_WINSOCK
- HMODULE wsock2;
- WSOCK2_FUNC close_event_func;
- WSOCK2_EVENT create_event_func;
- WSOCK2_FUNC event_select_func;
- WSOCK2_FUNC enum_netevents_func;
WSAEVENT event_handle;
WSANETWORKEVENTS events;
HANDLE stdin_handle;
@@ -1333,82 +1283,28 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
if(result)
return result;
- tn = (struct TELNET *)data->req.protop;
+ tn = data->req.p.telnet;
result = check_telnet_options(conn);
if(result)
return result;
#ifdef USE_WINSOCK
- /*
- ** This functionality only works with WinSock >= 2.0. So,
- ** make sure we have it.
- */
- result = check_wsock2(data);
- if(result)
- return result;
-
- /* OK, so we have WinSock 2.0. We need to dynamically */
- /* load ws2_32.dll and get the function pointers we need. */
- wsock2 = Curl_load_library(TEXT("WS2_32.DLL"));
- if(wsock2 == NULL) {
- failf(data, "failed to load WS2_32.DLL (%u)", GetLastError());
- return CURLE_FAILED_INIT;
- }
-
- /* Grab a pointer to WSACreateEvent */
- create_event_func =
- CURLX_FUNCTION_CAST(WSOCK2_EVENT,
- (GetProcAddress(wsock2, "WSACreateEvent")));
- if(create_event_func == NULL) {
- failf(data, "failed to find WSACreateEvent function (%u)", GetLastError());
- FreeLibrary(wsock2);
- return CURLE_FAILED_INIT;
- }
-
- /* And WSACloseEvent */
- close_event_func = GetProcAddress(wsock2, "WSACloseEvent");
- if(close_event_func == NULL) {
- failf(data, "failed to find WSACloseEvent function (%u)", GetLastError());
- FreeLibrary(wsock2);
- return CURLE_FAILED_INIT;
- }
-
- /* And WSAEventSelect */
- event_select_func = GetProcAddress(wsock2, "WSAEventSelect");
- if(event_select_func == NULL) {
- failf(data, "failed to find WSAEventSelect function (%u)", GetLastError());
- FreeLibrary(wsock2);
- return CURLE_FAILED_INIT;
- }
-
- /* And WSAEnumNetworkEvents */
- enum_netevents_func = GetProcAddress(wsock2, "WSAEnumNetworkEvents");
- if(enum_netevents_func == NULL) {
- failf(data, "failed to find WSAEnumNetworkEvents function (%u)",
- GetLastError());
- FreeLibrary(wsock2);
- return CURLE_FAILED_INIT;
- }
-
/* We want to wait for both stdin and the socket. Since
** the select() function in winsock only works on sockets
** we have to use the WaitForMultipleObjects() call.
*/
/* First, create a sockets event object */
- event_handle = (WSAEVENT)create_event_func();
+ event_handle = WSACreateEvent();
if(event_handle == WSA_INVALID_EVENT) {
failf(data, "WSACreateEvent failed (%d)", SOCKERRNO);
- FreeLibrary(wsock2);
return CURLE_FAILED_INIT;
}
/* Tell winsock what events we want to listen to */
- if(event_select_func(sockfd, event_handle, FD_READ|FD_CLOSE) ==
- SOCKET_ERROR) {
- close_event_func(event_handle);
- FreeLibrary(wsock2);
+ if(WSAEventSelect(sockfd, event_handle, FD_READ|FD_CLOSE) == SOCKET_ERROR) {
+ WSACloseEvent(event_handle);
return CURLE_OK;
}
@@ -1439,6 +1335,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
DWORD waitret = WaitForMultipleObjects(obj_count, objs,
FALSE, wait_timeout);
switch(waitret) {
+
case WAIT_TIMEOUT:
{
for(;;) {
@@ -1508,9 +1405,9 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
break;
case WAIT_OBJECT_0:
-
+ {
events.lNetworkEvents = 0;
- if(SOCKET_ERROR == enum_netevents_func(sockfd, event_handle, &events)) {
+ if(WSAEnumNetworkEvents(sockfd, event_handle, &events) == SOCKET_ERROR) {
err = SOCKERRNO;
if(err != EINPROGRESS) {
infof(data, "WSAEnumNetworkEvents failed (%d)", err);
@@ -1554,7 +1451,8 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
if(events.lNetworkEvents & FD_CLOSE) {
keepon = FALSE;
}
- break;
+ }
+ break;
}
@@ -1569,19 +1467,9 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
}
/* We called WSACreateEvent, so call WSACloseEvent */
- if(!close_event_func(event_handle)) {
+ if(!WSACloseEvent(event_handle)) {
infof(data, "WSACloseEvent failed (%d)", SOCKERRNO);
}
-
- /* "Forget" pointers into the library we're about to free */
- create_event_func = NULL;
- close_event_func = NULL;
- event_select_func = NULL;
- enum_netevents_func = NULL;
-
- /* We called LoadLibrary, so call FreeLibrary */
- if(!FreeLibrary(wsock2))
- infof(data, "FreeLibrary(wsock2) failed (%u)", GetLastError());
#else
pfd[0].fd = sockfd;
pfd[0].events = POLLIN;
diff --git a/lib/telnet.h b/lib/telnet.h
index 431427f39..1427473a9 100644
--- a/lib/telnet.h
+++ b/lib/telnet.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/tftp.c b/lib/tftp.c
index 7659fd40e..96b773c04 100644
--- a/lib/tftp.c
+++ b/lib/tftp.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -183,6 +183,7 @@ const struct Curl_handler Curl_handler_tftp = {
ZERO_NULL, /* connection_check */
PORT_TFTP, /* defport */
CURLPROTO_TFTP, /* protocol */
+ CURLPROTO_TFTP, /* family */
PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */
};
diff --git a/lib/tftp.h b/lib/tftp.h
index 33348300f..4b5bea275 100644
--- a/lib/tftp.h
+++ b/lib/tftp.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/timeval.c b/lib/timeval.c
index e761966a1..8523dad40 100644
--- a/lib/timeval.c
+++ b/lib/timeval.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/timeval.h b/lib/timeval.h
index 53e063607..685e72961 100644
--- a/lib/timeval.h
+++ b/lib/timeval.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/transfer.c b/lib/transfer.c
index 8c48bde69..8a2b3efc8 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -78,6 +78,7 @@
#include "mime.h"
#include "strcase.h"
#include "urlapi-int.h"
+#include "hsts.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -167,7 +168,7 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
bool sending_http_headers = FALSE;
if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) {
- const struct HTTP *http = data->req.protop;
+ const struct HTTP *http = data->req.p.http;
if(http->sending == HTTPSEND_REQUEST)
/* We're sending the HTTP request headers, not the data.
@@ -426,7 +427,7 @@ CURLcode Curl_readrewind(struct connectdata *conn)
CURLOPT_HTTPPOST, call app to rewind
*/
if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
- struct HTTP *http = data->req.protop;
+ struct HTTP *http = data->req.p.http;
if(http->sendit)
mimepart = http->sendit;
@@ -1028,7 +1029,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
/* HTTP pollution, this should be written nicer to become more
protocol agnostic. */
size_t fillcount;
- struct HTTP *http = k->protop;
+ struct HTTP *http = k->p.http;
if((k->exp100 == EXP100_SENDING_REQUEST) &&
(http->sending == HTTPSEND_BODY)) {
@@ -1152,10 +1153,9 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
win_update_buffer_size(conn->writesockfd);
- if(data->set.verbose)
- /* show the data before we change the pointer upload_fromhere */
- Curl_debug(data, CURLINFO_DATA_OUT, k->upload_fromhere,
- (size_t)bytes_written);
+ /* show the data before we change the pointer upload_fromhere */
+ Curl_debug(data, CURLINFO_DATA_OUT, k->upload_fromhere,
+ (size_t)bytes_written);
k->writebytecount += bytes_written;
Curl_pgrsSetUploadCounter(data, k->writebytecount);
@@ -1529,6 +1529,7 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
}
#endif
Curl_http2_init_state(&data->state);
+ Curl_hsts_loadcb(data, data->hsts);
}
return result;
@@ -1853,7 +1854,7 @@ Curl_setup_transfer(
{
struct SingleRequest *k = &data->req;
struct connectdata *conn = data->conn;
- struct HTTP *http = data->req.protop;
+ struct HTTP *http = data->req.p.http;
bool httpsending = ((conn->handler->protocol&PROTO_FAMILY_HTTP) &&
(http->sending == HTTPSEND_REQUEST));
DEBUGASSERT(conn != NULL);
diff --git a/lib/transfer.h b/lib/transfer.h
index 67fd91f25..178bb58fb 100644
--- a/lib/transfer.h
+++ b/lib/transfer.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/url.c b/lib/url.c
index 150667aa9..2b0ba87ba 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -96,6 +96,7 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
#include "getinfo.h"
#include "urlapi-int.h"
#include "system_win32.h"
+#include "hsts.h"
/* And now for the protocols */
#include "ftp.h"
@@ -130,7 +131,6 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
#include "memdebug.h"
static void conn_free(struct connectdata *conn);
-static unsigned int get_protocol_family(unsigned int protocol);
/* Some parts of the code (e.g. chunked encoding) assume this buffer has at
* more than just a few bytes to play with. Don't let it become too small or
@@ -140,6 +140,24 @@ static unsigned int get_protocol_family(unsigned int protocol);
# error READBUFFER_SIZE is too small
#endif
+/*
+* get_protocol_family()
+*
+* This is used to return the protocol family for a given protocol.
+*
+* Parameters:
+*
+* 'h' [in] - struct Curl_handler pointer.
+*
+* Returns the family as a single bit protocol identifier.
+*/
+static unsigned int get_protocol_family(const struct Curl_handler *h)
+{
+ DEBUGASSERT(h);
+ DEBUGASSERT(h->family);
+ return h->family;
+}
+
/*
* Protocol table. Schemes (roughly) in 2019 popularity order:
@@ -215,9 +233,8 @@ static const struct Curl_handler * const protocols[] = {
#endif
#endif
-#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
- (CURL_SIZEOF_CURL_OFF_T > 4) && \
- (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO))
+#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \
+ (CURL_SIZEOF_CURL_OFF_T > 4)
&Curl_handler_smb,
#ifdef USE_SSL
&Curl_handler_smbs,
@@ -228,7 +245,7 @@ static const struct Curl_handler * const protocols[] = {
&Curl_handler_rtsp,
#endif
-#ifdef CURL_ENABLE_MQTT
+#ifndef CURL_DISABLE_MQTT
&Curl_handler_mqtt,
#endif
@@ -274,6 +291,7 @@ static const struct Curl_handler Curl_handler_dummy = {
ZERO_NULL, /* connection_check */
0, /* defport */
0, /* protocol */
+ 0, /* family */
PROTOPT_NONE /* flags */
};
@@ -392,11 +410,10 @@ CURLcode Curl_close(struct Curl_easy **datap)
Curl_dyn_free(&data->state.headerb);
Curl_safefree(data->state.ulbuf);
Curl_flush_cookies(data, TRUE);
-#ifdef USE_ALTSVC
Curl_altsvc_save(data, data->asi, data->set.str[STRING_ALTSVC]);
- Curl_altsvc_cleanup(data->asi);
- data->asi = NULL;
-#endif
+ Curl_altsvc_cleanup(&data->asi);
+ Curl_hsts_save(data, data->hsts, data->set.str[STRING_HSTS]);
+ Curl_hsts_cleanup(&data->hsts);
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
Curl_http_auth_cleanup_digest(data);
#endif
@@ -480,6 +497,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */
set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */
set->ftp_filemethod = FTPFILE_MULTICWD;
+ set->ftp_skip_ip = TRUE; /* skip PASV IP by default */
#endif
set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
@@ -1019,7 +1037,7 @@ static void prune_dead_connections(struct Curl_easy *data)
Curl_conncache_remove_conn(data, prune.extracted, TRUE);
/* disconnect it */
- (void)Curl_disconnect(data, prune.extracted, /* dead_connection */TRUE);
+ (void)Curl_disconnect(data, prune.extracted, TRUE);
}
CONNCACHE_LOCK(data);
data->state.conn_cache->last_cleanup = now;
@@ -1075,7 +1093,7 @@ ConnectionExists(struct Curl_easy *data,
&hostbundle);
if(bundle) {
/* Max pipe length is zero (unlimited) for multiplexed connections */
- struct curl_llist_element *curr;
+ struct Curl_llist_element *curr;
infof(data, "Found bundle for host %s: %p [%s]\n",
hostbundle, (void *)bundle, (bundle->multiuse == BUNDLE_MULTIPLEX ?
@@ -1121,6 +1139,12 @@ ConnectionExists(struct Curl_easy *data,
/* connect-only or to-be-closed connections will not be reused */
continue;
+ if(extract_if_dead(check, data)) {
+ /* disconnect it */
+ (void)Curl_disconnect(data, check, TRUE);
+ continue;
+ }
+
if(bundle->multiuse == BUNDLE_MULTIPLEX)
multiplexed = CONN_INUSE(check);
@@ -1171,7 +1195,7 @@ ConnectionExists(struct Curl_easy *data,
if((needle->handler->flags&PROTOPT_SSL) !=
(check->handler->flags&PROTOPT_SSL))
/* don't do mixed SSL and non-SSL connections */
- if(get_protocol_family(check->handler->protocol) !=
+ if(get_protocol_family(check->handler) !=
needle->handler->protocol || !check->bits.tls_upgraded)
/* except protocols that have been upgraded via TLS */
continue;
@@ -1276,7 +1300,7 @@ ConnectionExists(struct Curl_easy *data,
is allowed to be upgraded via TLS */
if((strcasecompare(needle->handler->scheme, check->handler->scheme) ||
- (get_protocol_family(check->handler->protocol) ==
+ (get_protocol_family(check->handler) ==
needle->handler->protocol && check->bits.tls_upgraded)) &&
(!needle->bits.conn_to_host || strcasecompare(
needle->conn_to_host.name, check->conn_to_host.name)) &&
@@ -1891,6 +1915,37 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
if(uc)
return Curl_uc_to_curlcode(uc);
+ uc = curl_url_get(uh, CURLUPART_HOST, &data->state.up.hostname, 0);
+ if(uc) {
+ if(!strcasecompare("file", data->state.up.scheme))
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+#ifdef USE_HSTS
+ if(data->hsts && strcasecompare("http", data->state.up.scheme)) {
+ if(Curl_hsts(data->hsts, data->state.up.hostname, TRUE)) {
+ char *url;
+ Curl_safefree(data->state.up.scheme);
+ uc = curl_url_set(uh, CURLUPART_SCHEME, "https", 0);
+ if(uc)
+ return Curl_uc_to_curlcode(uc);
+ if(data->change.url_alloc)
+ Curl_safefree(data->change.url);
+ /* after update, get the updated version */
+ uc = curl_url_get(uh, CURLUPART_URL, &url, 0);
+ if(uc)
+ return Curl_uc_to_curlcode(uc);
+ uc = curl_url_get(uh, CURLUPART_SCHEME, &data->state.up.scheme, 0);
+ if(uc)
+ return Curl_uc_to_curlcode(uc);
+ data->change.url = url;
+ data->change.url_alloc = TRUE;
+ infof(data, "Switched from HTTP to HTTPS due to HSTS => %s\n",
+ data->change.url);
+ }
+ }
+#endif
+
result = findprotocol(data, conn, data->state.up.scheme);
if(result)
return result;
@@ -1936,12 +1991,6 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
else if(uc != CURLUE_NO_OPTIONS)
return Curl_uc_to_curlcode(uc);
- uc = curl_url_get(uh, CURLUPART_HOST, &data->state.up.hostname, 0);
- if(uc) {
- if(!strcasecompare("file", data->state.up.scheme))
- return CURLE_OUT_OF_MEMORY;
- }
-
uc = curl_url_get(uh, CURLUPART_PATH, &data->state.up.path, 0);
if(uc)
return Curl_uc_to_curlcode(uc);
@@ -2060,7 +2109,7 @@ static CURLcode setup_connection_internals(struct connectdata *conn)
void Curl_free_request_state(struct Curl_easy *data)
{
- Curl_safefree(data->req.protop);
+ Curl_safefree(data->req.p.http);
Curl_safefree(data->req.newurl);
#ifndef CURL_DISABLE_DOH
@@ -2377,8 +2426,10 @@ static CURLcode parse_proxy(struct Curl_easy *data,
static CURLcode parse_proxy_auth(struct Curl_easy *data,
struct connectdata *conn)
{
- char *proxyuser = data->set.str[STRING_PROXYUSERNAME];
- char *proxypasswd = data->set.str[STRING_PROXYPASSWORD];
+ const char *proxyuser = data->set.str[STRING_PROXYUSERNAME] ?
+ data->set.str[STRING_PROXYUSERNAME] : "";
+ const char *proxypasswd = data->set.str[STRING_PROXYPASSWORD] ?
+ data->set.str[STRING_PROXYPASSWORD] : "";
CURLcode result = CURLE_OK;
if(proxyuser)
@@ -2551,6 +2602,9 @@ static CURLcode create_conn_helper_init_proxy(struct connectdata *conn)
conn->bits.socksproxy = FALSE;
conn->bits.proxy_user_passwd = FALSE;
conn->bits.tunnel_proxy = FALSE;
+ /* CURLPROXY_HTTPS does not have its own flag in conn->bits, yet we need
+ to signal that CURLPROXY_HTTPS is not used for this connection */
+ conn->http_proxy.proxytype = CURLPROXY_HTTP;
}
out:
@@ -3070,7 +3124,7 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data,
conn_to_host = conn_to_host->next;
}
-#ifdef USE_ALTSVC
+#ifndef CURL_DISABLE_ALTSVC
if(data->asi && !host && (port == -1) &&
((conn->handler->protocol == CURLPROTO_HTTPS) ||
#ifdef CURLDEBUG
@@ -3611,6 +3665,7 @@ static CURLcode create_conn(struct Curl_easy *data,
data->set.ssl.primary.pinned_key =
data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
data->set.ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_ORIG];
+ data->set.ssl.primary.curves = data->set.str[STRING_SSL_EC_CURVES];
#ifndef CURL_DISABLE_PROXY
data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];
@@ -3627,18 +3682,15 @@ static CURLcode create_conn(struct Curl_easy *data,
data->set.proxy_ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_PROXY];
data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY];
data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY];
- data->set.proxy_ssl.cert = data->set.str[STRING_CERT_PROXY];
data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY];
data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY];
data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY];
data->set.proxy_ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY];
data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY];
- data->set.proxy_ssl.cert_blob = data->set.blobs[BLOB_CERT_PROXY];
data->set.proxy_ssl.key_blob = data->set.blobs[BLOB_KEY_PROXY];
#endif
data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG];
data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG];
- data->set.ssl.cert = data->set.str[STRING_CERT_ORIG];
data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG];
data->set.ssl.key = data->set.str[STRING_KEY_ORIG];
data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE_ORIG];
@@ -3653,7 +3705,6 @@ static CURLcode create_conn(struct Curl_easy *data,
#endif
#endif
- data->set.ssl.cert_blob = data->set.blobs[BLOB_CERT_ORIG];
data->set.ssl.key_blob = data->set.blobs[BLOB_KEY_ORIG];
data->set.ssl.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT_ORIG];
@@ -3752,8 +3803,7 @@ static CURLcode create_conn(struct Curl_easy *data,
CONNCACHE_UNLOCK(data);
if(conn_candidate)
- (void)Curl_disconnect(data, conn_candidate,
- /* dead_connection */ FALSE);
+ (void)Curl_disconnect(data, conn_candidate, FALSE);
else {
infof(data, "No more connections allowed to host %s: %zu\n",
bundlehost, max_host_connections);
@@ -3773,8 +3823,7 @@ static CURLcode create_conn(struct Curl_easy *data,
/* The cache is full. Let's see if we can kill a connection. */
conn_candidate = Curl_conncache_extract_oldest(data);
if(conn_candidate)
- (void)Curl_disconnect(data, conn_candidate,
- /* dead_connection */ FALSE);
+ (void)Curl_disconnect(data, conn_candidate, FALSE);
else {
infof(data, "No connections available in cache\n");
connections_available = FALSE;
@@ -4026,113 +4075,3 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn)
return CURLE_OK;
}
-
-/*
-* get_protocol_family()
-*
-* This is used to return the protocol family for a given protocol.
-*
-* Parameters:
-*
-* protocol [in] - A single bit protocol identifier such as HTTP or HTTPS.
-*
-* Returns the family as a single bit protocol identifier.
-*/
-
-static unsigned int get_protocol_family(unsigned int protocol)
-{
- unsigned int family;
-
- switch(protocol) {
- case CURLPROTO_HTTP:
- case CURLPROTO_HTTPS:
- family = CURLPROTO_HTTP;
- break;
-
- case CURLPROTO_FTP:
- case CURLPROTO_FTPS:
- family = CURLPROTO_FTP;
- break;
-
- case CURLPROTO_SCP:
- family = CURLPROTO_SCP;
- break;
-
- case CURLPROTO_SFTP:
- family = CURLPROTO_SFTP;
- break;
-
- case CURLPROTO_TELNET:
- family = CURLPROTO_TELNET;
- break;
-
- case CURLPROTO_LDAP:
- case CURLPROTO_LDAPS:
- family = CURLPROTO_LDAP;
- break;
-
- case CURLPROTO_DICT:
- family = CURLPROTO_DICT;
- break;
-
- case CURLPROTO_FILE:
- family = CURLPROTO_FILE;
- break;
-
- case CURLPROTO_TFTP:
- family = CURLPROTO_TFTP;
- break;
-
- case CURLPROTO_IMAP:
- case CURLPROTO_IMAPS:
- family = CURLPROTO_IMAP;
- break;
-
- case CURLPROTO_POP3:
- case CURLPROTO_POP3S:
- family = CURLPROTO_POP3;
- break;
-
- case CURLPROTO_SMTP:
- case CURLPROTO_SMTPS:
- family = CURLPROTO_SMTP;
- break;
-
- case CURLPROTO_RTSP:
- family = CURLPROTO_RTSP;
- break;
-
- case CURLPROTO_RTMP:
- case CURLPROTO_RTMPS:
- family = CURLPROTO_RTMP;
- break;
-
- case CURLPROTO_RTMPT:
- case CURLPROTO_RTMPTS:
- family = CURLPROTO_RTMPT;
- break;
-
- case CURLPROTO_RTMPE:
- family = CURLPROTO_RTMPE;
- break;
-
- case CURLPROTO_RTMPTE:
- family = CURLPROTO_RTMPTE;
- break;
-
- case CURLPROTO_GOPHER:
- family = CURLPROTO_GOPHER;
- break;
-
- case CURLPROTO_SMB:
- case CURLPROTO_SMBS:
- family = CURLPROTO_SMB;
- break;
-
- default:
- family = 0;
- break;
- }
-
- return family;
-}
diff --git a/lib/url.h b/lib/url.h
index 1941dc6a4..a9d5bda29 100644
--- a/lib/url.h
+++ b/lib/url.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/urlapi-int.h b/lib/urlapi-int.h
index d14d53d97..425723309 100644
--- a/lib/urlapi-int.h
+++ b/lib/urlapi-int.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -28,7 +28,7 @@
bool Curl_is_absolute_url(const char *url, char *scheme, size_t buflen);
#ifdef DEBUGBUILD
-CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname);
+CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname, bool);
#endif
#endif /* HEADER_CURL_URLAPI_INT_H */
diff --git a/lib/urlapi.c b/lib/urlapi.c
index acbfb8287..ae7596359 100644
--- a/lib/urlapi.c
+++ b/lib/urlapi.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -497,7 +497,8 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u,
return result;
}
-UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname)
+UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname,
+ bool has_scheme)
{
char *portptr = NULL;
char endbracket;
@@ -542,10 +543,14 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname)
/* Browser behavior adaptation. If there's a colon with no digits after,
just cut off the name there which makes us ignore the colon and just
- use the default port. Firefox, Chrome and Safari all do that. */
+ use the default port. Firefox, Chrome and Safari all do that.
+
+ Don't do it if the URL has no scheme, to make something that looks like
+ a scheme not work!
+ */
if(!portptr[1]) {
*portptr = '\0';
- return CURLUE_OK;
+ return has_scheme ? CURLUE_OK : CURLUE_BAD_PORT_NUMBER;
}
if(!ISDIGIT(portptr[1]))
@@ -904,7 +909,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
if(result)
return result;
- result = Curl_parse_port(u, hostname);
+ result = Curl_parse_port(u, hostname, url_has_scheme);
if(result)
return result;
@@ -1255,8 +1260,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
return CURLUE_UNKNOWN_PART;
}
if(storep && *storep) {
- free(*storep);
- *storep = NULL;
+ Curl_safefree(*storep);
}
return CURLUE_OK;
}
@@ -1284,8 +1288,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
break;
case CURLUPART_HOST:
storep = &u->host;
- free(u->zoneid);
- u->zoneid = NULL;
+ Curl_safefree(u->zoneid);
break;
case CURLUPART_ZONEID:
storep = &u->zoneid;
@@ -1389,28 +1392,17 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
if(urlencode) {
const unsigned char *i;
char *o;
- bool free_part = FALSE;
char *enc = malloc(nalloc * 3 + 1); /* for worst case! */
if(!enc)
return CURLUE_OUT_OF_MEMORY;
- if(plusencode) {
- /* space to plus */
- i = (const unsigned char *)part;
- for(o = enc; *i; ++o, ++i)
- *o = (*i == ' ') ? '+' : *i;
- *o = 0; /* null-terminate */
- part = strdup(enc);
- if(!part) {
- free(enc);
- return CURLUE_OUT_OF_MEMORY;
- }
- free_part = TRUE;
- }
for(i = (const unsigned char *)part, o = enc; *i; i++) {
- if(Curl_isunreserved(*i) ||
- ((*i == '/') && urlskipslash) ||
- ((*i == '=') && equalsencode) ||
- ((*i == '+') && plusencode)) {
+ if((*i == ' ') && plusencode) {
+ *o = '+';
+ o++;
+ }
+ else if(Curl_isunreserved(*i) ||
+ ((*i == '/') && urlskipslash) ||
+ ((*i == '=') && equalsencode)) {
if((*i == '=') && equalsencode)
/* only skip the first equals sign */
equalsencode = FALSE;
@@ -1424,8 +1416,6 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
}
*o = 0; /* null-terminate */
newp = enc;
- if(free_part)
- free((char *)part);
}
else {
char *p;
diff --git a/lib/urldata.h b/lib/urldata.h
index 5bfa412a2..1be7ddc39 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -76,9 +76,7 @@
/* length of longest IPv6 address string including the trailing null */
#define MAX_IPADR_LEN sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")
-/* Default FTP/IMAP etc response timeout in milliseconds.
- Symbian OS panics when given a timeout much greater than 1/2 hour.
-*/
+/* Default FTP/IMAP etc response timeout in milliseconds */
#define RESP_TIMEOUT (120*1000)
/* Max string input length is a precaution against abuse and to detect junk
@@ -207,15 +205,15 @@ struct ssl_backend_data;
/* struct for data related to each SSL connection */
struct ssl_connect_data {
- /* Use ssl encrypted communications TRUE/FALSE, not necessarily using it atm
- but at least asked to or meaning to use it. See 'state' for the exact
- current state of the connection. */
ssl_connection_state state;
ssl_connect_state connecting_state;
#if defined(USE_SSL)
struct ssl_backend_data *backend;
#endif
+ /* Use ssl encrypted communications TRUE/FALSE. The library is not
+ necessarily using ssl at the moment but at least asked to or means to use
+ it. See 'state' for the exact current state of the connection. */
BIT(use);
};
@@ -231,6 +229,7 @@ struct ssl_primary_config {
char *cipher_list13; /* list of TLS 1.3 cipher suites to use */
char *pinned_key;
struct curl_blob *cert_blob;
+ char *curves; /* list of curves to use */
BIT(verifypeer); /* set TRUE if this is desired */
BIT(verifyhost); /* set TRUE if CN/SAN must match hostname */
BIT(verifystatus); /* set TRUE if certificate status must be checked */
@@ -245,8 +244,6 @@ struct ssl_config_data {
struct curl_blob *issuercert_blob;
curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */
void *fsslctxp; /* parameter for call back */
- char *cert; /* client certificate file name */
- struct curl_blob *cert_blob;
char *cert_type; /* format for certificate (default: PEM)*/
char *key; /* private key file name */
struct curl_blob *key_blob;
@@ -272,7 +269,7 @@ struct ssl_general_config {
};
/* information stored about one single SSL session */
-struct curl_ssl_session {
+struct Curl_ssl_session {
char *name; /* host name for which this ID was used */
char *conn_to_host; /* host name for the connection (may be NULL) */
const char *scheme; /* protocol scheme used */
@@ -473,6 +470,7 @@ struct ConnectBits {
EPRT doesn't work we disable it for the forthcoming
requests */
BIT(ftp_use_data_ssl); /* Enabled SSL for the data connection */
+ BIT(ftp_use_control_ssl); /* Enabled SSL for the control connection */
#endif
BIT(netrc); /* name+password provided by netrc */
BIT(bound); /* set true if bind() has already been done on this socket/
@@ -522,7 +520,7 @@ struct Curl_async {
int port;
struct Curl_dns_entry *dns;
int status; /* if done is TRUE, this is the status from the callback */
- void *os_specific; /* 'struct thread_data' for Windows */
+ struct thread_data *tdata;
BIT(done); /* set TRUE when the lookup is complete */
};
@@ -646,8 +644,23 @@ struct SingleRequest {
and the 'upload_present' contains the number of bytes available at this
position */
char *upload_fromhere;
- void *protop; /* Allocated protocol-specific data. Each protocol
- handler makes sure this points to data it needs. */
+
+ /* Allocated protocol-specific data. Each protocol handler makes sure this
+ points to data it needs. */
+ union {
+ struct FILEPROTO *file;
+ struct FTP *ftp;
+ struct HTTP *http;
+ struct IMAP *imap;
+ struct ldapreqinfo *ldap;
+ struct MQTT *mqtt;
+ struct POP3 *pop3;
+ struct RTSP *rtsp;
+ struct smb_request *smb;
+ struct SMTP *smtp;
+ struct SSHPROTO *ssh;
+ struct TELNET *telnet;
+ } p;
#ifndef CURL_DISABLE_DOH
struct dohdata doh; /* DoH specific data for this request */
#endif
@@ -741,6 +754,8 @@ struct Curl_handler {
long defport; /* Default port. */
unsigned int protocol; /* See CURLPROTO_* - this needs to be the single
specific protocol bit */
+ unsigned int family; /* single bit for protocol family; basically the
+ non-TLS name of the protocol this is */
unsigned int flags; /* Extra particular characteristics, see PROTOPT_* */
};
@@ -803,7 +818,11 @@ struct proxy_info {
/* struct for HTTP CONNECT state data */
struct http_connect_state {
struct dynbuf rcvbuf;
- int keepon;
+ enum keeponval {
+ KEEPON_DONE,
+ KEEPON_CONNECT,
+ KEEPON_IGNORE
+ } keepon;
curl_off_t cl; /* size of content to read and ignore */
enum {
TUNNEL_INIT, /* init/default/no tunnel state */
@@ -861,7 +880,7 @@ struct connectdata {
connection is used! */
struct Curl_easy *data;
struct connstate cnnct;
- struct curl_llist_element bundle_node; /* conncache */
+ struct Curl_llist_element bundle_node; /* conncache */
/* chunk is for HTTP chunked encoding, but is in the general connectdata
struct only because we can do just about any protocol through a HTTP proxy
@@ -1025,7 +1044,7 @@ struct connectdata {
struct kerberos5data krb5; /* variables into the structure definition, */
#endif /* however, some of them are ftp specific. */
- struct curl_llist easyq; /* List of easy handles using this connection */
+ struct Curl_llist easyq; /* List of easy handles using this connection */
curl_seek_callback seek_func; /* function that seeks the input */
void *seek_client; /* pointer to pass to the seek() above */
@@ -1135,6 +1154,7 @@ struct PureInfo {
OpenSSL, GnuTLS, Schannel, NSS and GSKit
builds. Asked for with CURLOPT_CERTINFO
/ CURLINFO_CERTINFO */
+ CURLproxycode pxcode;
BIT(timecond); /* set to TRUE if the time condition didn't match, which
thus made the document NOT get fetched */
};
@@ -1275,7 +1295,7 @@ typedef enum {
* One instance for each timeout an easy handle can set.
*/
struct time_node {
- struct curl_llist_element list;
+ struct Curl_llist_element list;
struct curltime time;
expire_id eid;
};
@@ -1315,7 +1335,7 @@ struct UrlState {
strdup() data.
*/
int first_remote_port; /* remote port of the first (not followed) request */
- struct curl_ssl_session *session; /* array of 'max_ssl_sessions' size */
+ struct Curl_ssl_session *session; /* array of 'max_ssl_sessions' size */
long sessionage; /* number of the most recent session */
unsigned int tempcount; /* number of entries in use in tempwrite, 0 - 3 */
struct tempbuf tempwrite[3]; /* BOTH, HEADER, BODY */
@@ -1339,7 +1359,7 @@ struct UrlState {
#endif /* USE_OPENSSL */
struct curltime expiretime; /* set this with Curl_expire() only */
struct Curl_tree timenode; /* for the splay stuff */
- struct curl_llist timeoutlist; /* list of pending timeouts */
+ struct Curl_llist timeoutlist; /* list of pending timeouts */
struct time_node expires[EXPIRE_LAST]; /* nodes for each expire type */
/* a place to store the most recently set FTP entrypath */
@@ -1348,8 +1368,7 @@ struct UrlState {
int httpversion; /* the lowest HTTP version*10 reported by any server
involved in this request */
-#if !defined(WIN32) && !defined(MSDOS) && !defined(__EMX__) && \
- !defined(__SYMBIAN32__)
+#if !defined(WIN32) && !defined(MSDOS) && !defined(__EMX__)
/* do FTP line-end conversions on most platforms */
#define CURL_DO_LINEEND_CONV
/* for FTP downloads: track CRLF sequences that span blocks */
@@ -1532,39 +1551,31 @@ enum dupstring {
STRING_RTSP_SESSION_ID, /* Session ID to use */
STRING_RTSP_STREAM_URI, /* Stream URI for this request */
STRING_RTSP_TRANSPORT, /* Transport for this session */
-
STRING_SSH_PRIVATE_KEY, /* path to the private key file for auth */
STRING_SSH_PUBLIC_KEY, /* path to the public key file for auth */
STRING_SSH_HOST_PUBLIC_KEY_MD5, /* md5 of host public key in ascii hex */
STRING_SSH_KNOWNHOSTS, /* file name of knownhosts file */
-
STRING_PROXY_SERVICE_NAME, /* Proxy service name */
STRING_SERVICE_NAME, /* Service name */
STRING_MAIL_FROM,
STRING_MAIL_AUTH,
-
STRING_TLSAUTH_USERNAME_ORIG, /* TLS auth <username> */
STRING_TLSAUTH_USERNAME_PROXY, /* TLS auth <username> */
STRING_TLSAUTH_PASSWORD_ORIG, /* TLS auth <password> */
STRING_TLSAUTH_PASSWORD_PROXY, /* TLS auth <password> */
-
STRING_BEARER, /* <bearer>, if used */
-
STRING_UNIX_SOCKET_PATH, /* path to Unix socket, if used */
-
STRING_TARGET, /* CURLOPT_REQUEST_TARGET */
STRING_DOH, /* CURLOPT_DOH_URL */
-
STRING_ALTSVC, /* CURLOPT_ALTSVC */
-
+ STRING_HSTS, /* CURLOPT_HSTS */
STRING_SASL_AUTHZID, /* CURLOPT_SASL_AUTHZID */
-
STRING_TEMP_URL, /* temp URL storage for proxy use */
-
STRING_DNS_SERVERS,
STRING_DNS_INTERFACE,
STRING_DNS_LOCAL_IP4,
STRING_DNS_LOCAL_IP6,
+ STRING_SSL_EC_CURVES,
/* -- end of null-terminated strings -- */
@@ -1648,7 +1659,12 @@ struct UserDefined {
curl_conv_callback convtonetwork;
/* function to convert from UTF-8 encoding: */
curl_conv_callback convfromutf8;
-
+#ifdef USE_HSTS
+ curl_hstsread_callback hsts_read;
+ void *hsts_read_userp;
+ curl_hstswrite_callback hsts_write;
+ void *hsts_write_userp;
+#endif
void *progress_client; /* pointer to pass to the progress callback */
void *ioctl_client; /* pointer to pass to the ioctl callback */
long timeout; /* in milliseconds, 0 means no timeout */
@@ -1840,7 +1856,7 @@ struct UserDefined {
};
struct Names {
- struct curl_hash *hostcache;
+ struct Curl_hash *hostcache;
enum {
HCACHE_NONE, /* not pointing to anything */
HCACHE_MULTI, /* points to a shared one in the multi handle */
@@ -1864,8 +1880,8 @@ struct Curl_easy {
struct Curl_easy *prev;
struct connectdata *conn;
- struct curl_llist_element connect_queue;
- struct curl_llist_element conn_queue; /* list per connectdata */
+ struct Curl_llist_element connect_queue;
+ struct Curl_llist_element conn_queue; /* list per connectdata */
CURLMstate mstate; /* the handle's state */
CURLcode result; /* previous result */
@@ -1899,7 +1915,10 @@ struct Curl_easy {
NOTE that the 'cookie' field in the
UserDefined struct defines if the "engine"
is to be used or not. */
-#ifdef USE_ALTSVC
+#ifdef USE_HSTS
+ struct hsts *hsts;
+#endif
+#ifndef CURL_DISABLE_ALTSVC
struct altsvcinfo *asi; /* the alt-svc cache */
#endif
struct Progress progress; /* for all the progress meter data */
diff --git a/lib/vauth/cleartext.c b/lib/vauth/cleartext.c
index 27a10e793..25c1ee7da 100644
--- a/lib/vauth/cleartext.c
+++ b/lib/vauth/cleartext.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/cram.c b/lib/vauth/cram.c
index e7ab1366f..7399d5d59 100644
--- a/lib/vauth/cram.c
+++ b/lib/vauth/cram.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/digest.c b/lib/vauth/digest.c
index 9768ab617..50ea12c7d 100644
--- a/lib/vauth/digest.c
+++ b/lib/vauth/digest.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/digest.h b/lib/vauth/digest.h
index 343c94e90..95febe1ef 100644
--- a/lib/vauth/digest.h
+++ b/lib/vauth/digest.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/digest_sspi.c b/lib/vauth/digest_sspi.c
index 0792757b7..73666dc56 100644
--- a/lib/vauth/digest_sspi.c
+++ b/lib/vauth/digest_sspi.c
@@ -10,7 +10,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/krb5_gssapi.c b/lib/vauth/krb5_gssapi.c
index b7e64712b..c39bf4ed6 100644
--- a/lib/vauth/krb5_gssapi.c
+++ b/lib/vauth/krb5_gssapi.c
@@ -6,11 +6,11 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2014 - 2019, Steve Holme, <steve_holme@hotmail.com>.
- * Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2015 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/krb5_sspi.c b/lib/vauth/krb5_sspi.c
index b2efdb43d..4f0ddc453 100644
--- a/lib/vauth/krb5_sspi.c
+++ b/lib/vauth/krb5_sspi.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/ntlm.c b/lib/vauth/ntlm.c
index ecfeacb9a..a3117f3fe 100644
--- a/lib/vauth/ntlm.c
+++ b/lib/vauth/ntlm.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -497,7 +497,6 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
const char *passwdp,
struct ntlmdata *ntlm,
char **outptr, size_t *outlen)
-
{
/* NTLM type-3 message structure:
diff --git a/lib/vauth/ntlm.h b/lib/vauth/ntlm.h
index 1136b0f8d..8ec23ad4f 100644
--- a/lib/vauth/ntlm.h
+++ b/lib/vauth/ntlm.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/ntlm_sspi.c b/lib/vauth/ntlm_sspi.c
index e747abb75..532132778 100644
--- a/lib/vauth/ntlm_sspi.c
+++ b/lib/vauth/ntlm_sspi.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/oauth2.c b/lib/vauth/oauth2.c
index 6db148b62..a738851e8 100644
--- a/lib/vauth/oauth2.c
+++ b/lib/vauth/oauth2.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/spnego_gssapi.c b/lib/vauth/spnego_gssapi.c
index afd765db7..c81e945cf 100644
--- a/lib/vauth/spnego_gssapi.c
+++ b/lib/vauth/spnego_gssapi.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/spnego_sspi.c b/lib/vauth/spnego_sspi.c
index 97220a5ad..246976d62 100644
--- a/lib/vauth/spnego_sspi.c
+++ b/lib/vauth/spnego_sspi.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/vauth.c b/lib/vauth/vauth.c
index 1b3ff5ada..bdb78972f 100644
--- a/lib/vauth/vauth.c
+++ b/lib/vauth/vauth.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/vauth.h b/lib/vauth/vauth.h
index b5c5b7165..81e4df5d2 100644
--- a/lib/vauth/vauth.h
+++ b/lib/vauth/vauth.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2014 - 2019, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2014 - 2020, Steve Holme, <steve_holme@hotmail.com>.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/version.c b/lib/version.c
index 120176500..e55d9a705 100644
--- a/lib/version.c
+++ b/lib/version.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -31,8 +31,8 @@
#include "curl_printf.h"
#ifdef USE_ARES
-# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
- (defined(WIN32) || defined(__SYMBIAN32__))
+# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
+ defined(WIN32)
# define CARES_STATICLIB
# endif
# include <ares.h>
@@ -56,10 +56,6 @@
#ifdef HAVE_ZLIB_H
#include <zlib.h>
-#ifdef __SYMBIAN32__
-/* zlib pollutes the namespace with this definition */
-#undef WIN32
-#endif
#endif
#ifdef HAVE_BROTLI
@@ -298,7 +294,7 @@ static const char * const protocols[] = {
"ldaps",
#endif
#endif
-#ifdef CURL_ENABLE_MQTT
+#ifndef CURL_DISABLE_MQTT
"mqtt",
#endif
#ifndef CURL_DISABLE_POP3
@@ -319,9 +315,8 @@ static const char * const protocols[] = {
#ifdef USE_SSH
"sftp",
#endif
-#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
- (CURL_SIZEOF_CURL_OFF_T > 4) && \
- (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO))
+#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \
+ (CURL_SIZEOF_CURL_OFF_T > 4)
"smb",
# ifdef USE_SSL
"smbs",
@@ -420,9 +415,12 @@ static curl_version_info_data version_info = {
#if defined(HAVE_ZSTD)
| CURL_VERSION_ZSTD
#endif
-#if defined(USE_ALTSVC)
+#ifndef CURL_DISABLE_ALTSVC
| CURL_VERSION_ALTSVC
#endif
+#if defined(USE_HSTS)
+ | CURL_VERSION_HSTS
+#endif
,
NULL, /* ssl_version */
0, /* ssl_version_num, this is kept at zero */
@@ -475,11 +473,13 @@ curl_version_info_data *curl_version_info(CURLversion stamp)
#ifdef USE_SSL
Curl_ssl_version(ssl_buffer, sizeof(ssl_buffer));
version_info.ssl_version = ssl_buffer;
+#ifndef CURL_DISABLE_PROXY
if(Curl_ssl->supports & SSLSUPP_HTTPS_PROXY)
version_info.features |= CURL_VERSION_HTTPS_PROXY;
else
version_info.features &= ~CURL_VERSION_HTTPS_PROXY;
#endif
+#endif
#ifdef HAVE_LIBZ
version_info.libz_version = zlibVersion();
diff --git a/lib/version_win32.c b/lib/version_win32.c
index a1d1175aa..c8b10d104 100644
--- a/lib/version_win32.c
+++ b/lib/version_win32.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/version_win32.h b/lib/version_win32.h
index 94cc62667..9b1bd8887 100644
--- a/lib/version_win32.h
+++ b/lib/version_win32.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vquic/ngtcp2.c b/lib/vquic/ngtcp2.c
index 20ee08dd6..0f2fea0af 100644
--- a/lib/vquic/ngtcp2.c
+++ b/lib/vquic/ngtcp2.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -126,7 +126,7 @@ quic_from_ossl_level(OSSL_ENCRYPTION_LEVEL ossl_level)
case ssl_encryption_handshake:
return NGTCP2_CRYPTO_LEVEL_HANDSHAKE;
case ssl_encryption_application:
- return NGTCP2_CRYPTO_LEVEL_APP;
+ return NGTCP2_CRYPTO_LEVEL_APPLICATION;
default:
assert(0);
}
@@ -143,7 +143,7 @@ quic_from_gtls_level(gnutls_record_encryption_level_t gtls_level)
case GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE:
return NGTCP2_CRYPTO_LEVEL_HANDSHAKE;
case GNUTLS_ENCRYPTION_LEVEL_APPLICATION:
- return NGTCP2_CRYPTO_LEVEL_APP;
+ return NGTCP2_CRYPTO_LEVEL_APPLICATION;
default:
assert(0);
}
@@ -265,7 +265,7 @@ static int quic_set_encryption_secrets(SSL *ssl,
qs->qconn, NULL, NULL, NULL, level, tx_secret, secretlen) != 0)
return 0;
- if(level == NGTCP2_CRYPTO_LEVEL_APP) {
+ if(level == NGTCP2_CRYPTO_LEVEL_APPLICATION) {
if(init_ngh3_conn(qs) != CURLE_OK)
return 0;
}
@@ -349,14 +349,8 @@ static int quic_init_ssl(struct quicsocket *qs)
SSL_set_app_data(qs->ssl, qs);
SSL_set_connect_state(qs->ssl);
- switch(qs->version) {
-#ifdef NGTCP2_PROTO_VER
- case NGTCP2_PROTO_VER:
- alpn = (const uint8_t *)NGHTTP3_ALPN_H3;
- alpnlen = sizeof(NGHTTP3_ALPN_H3) - 1;
- break;
-#endif
- }
+ alpn = (const uint8_t *)NGHTTP3_ALPN_H3;
+ alpnlen = sizeof(NGHTTP3_ALPN_H3) - 1;
if(alpn)
SSL_set_alpn_protos(qs->ssl, alpn, (int)alpnlen);
@@ -382,7 +376,7 @@ static int secret_func(gnutls_session_t ssl,
qs->qconn, NULL, NULL, NULL, level, tx_secret, secretlen) != 0)
return 0;
- if(level == NGTCP2_CRYPTO_LEVEL_APP) {
+ if(level == NGTCP2_CRYPTO_LEVEL_APPLICATION) {
if(init_ngh3_conn(qs) != CURLE_OK)
return -1;
}
@@ -532,15 +526,9 @@ static int quic_init_ssl(struct quicsocket *qs)
return 1;
}
- switch(qs->version) {
-#ifdef NGTCP2_PROTO_VER
- case NGTCP2_PROTO_VER:
- /* strip the first byte (the length) from NGHTTP3_ALPN_H3 */
- alpn.data = (unsigned char *)NGHTTP3_ALPN_H3 + 1;
- alpn.size = sizeof(NGHTTP3_ALPN_H3) - 2;
- break;
-#endif
- }
+ /* strip the first byte (the length) from NGHTTP3_ALPN_H3 */
+ alpn.data = (unsigned char *)NGHTTP3_ALPN_H3 + 1;
+ alpn.size = sizeof(NGHTTP3_ALPN_H3) - 2;
if(alpn.data)
gnutls_alpn_set_protocols(qs->ssl, &alpn, 1, 0);
@@ -798,7 +786,7 @@ CURLcode Curl_quic_connect(struct connectdata *conn,
infof(data, "Connect socket %d over QUIC to %s:%ld\n",
sockfd, ipbuf, port);
- qs->version = NGTCP2_PROTO_VER;
+ qs->version = NGTCP2_PROTO_VER_MAX;
#ifdef USE_OPENSSL
qs->sslctx = quic_ssl_ctx(data);
if(!qs->sslctx)
@@ -828,16 +816,13 @@ CURLcode Curl_quic_connect(struct connectdata *conn,
if(rv == -1)
return CURLE_QUIC_CONNECT_ERROR;
- ngtcp2_addr_init(&path.local, &qs->local_addr, qs->local_addrlen, NULL);
+ ngtcp2_addr_init(&path.local, (struct sockaddr *)&qs->local_addr,
+ qs->local_addrlen, NULL);
ngtcp2_addr_init(&path.remote, addr, addrlen, NULL);
-#ifdef NGTCP2_PROTO_VER
-#define QUICVER NGTCP2_PROTO_VER
-#else
-#error "unsupported ngtcp2 version"
-#endif
- rc = ngtcp2_conn_client_new(&qs->qconn, &qs->dcid, &qs->scid, &path, QUICVER,
- &ng_callbacks, &qs->settings, NULL, qs);
+ rc = ngtcp2_conn_client_new(&qs->qconn, &qs->dcid, &qs->scid, &path,
+ NGTCP2_PROTO_VER_MIN, &ng_callbacks,
+ &qs->settings, NULL, qs);
if(rc)
return CURLE_QUIC_CONNECT_ERROR;
@@ -954,6 +939,7 @@ static const struct Curl_handler Curl_handler_http3 = {
ng_conncheck, /* connection_check */
PORT_HTTP, /* defport */
CURLPROTO_HTTPS, /* protocol */
+ CURLPROTO_HTTP, /* family */
PROTOPT_SSL | PROTOPT_STREAM /* flags */
};
@@ -962,7 +948,7 @@ static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id,
void *stream_user_data)
{
struct Curl_easy *data = stream_user_data;
- struct HTTP *stream = data->req.protop;
+ struct HTTP *stream = data->req.p.http;
(void)conn;
(void)stream_id;
(void)app_error_code;
@@ -1008,7 +994,7 @@ static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream_id,
void *user_data, void *stream_user_data)
{
struct Curl_easy *data = stream_user_data;
- struct HTTP *stream = data->req.protop;
+ struct HTTP *stream = data->req.p.http;
CURLcode result = CURLE_OK;
(void)conn;
@@ -1067,7 +1053,7 @@ static int cb_h3_end_headers(nghttp3_conn *conn, int64_t stream_id,
void *user_data, void *stream_user_data)
{
struct Curl_easy *data = stream_user_data;
- struct HTTP *stream = data->req.protop;
+ struct HTTP *stream = data->req.p.http;
CURLcode result = CURLE_OK;
(void)conn;
(void)stream_id;
@@ -1091,7 +1077,7 @@ static int cb_h3_recv_header(nghttp3_conn *conn, int64_t stream_id,
nghttp3_vec h3name = nghttp3_rcbuf_get_buf(name);
nghttp3_vec h3val = nghttp3_rcbuf_get_buf(value);
struct Curl_easy *data = stream_user_data;
- struct HTTP *stream = data->req.protop;
+ struct HTTP *stream = data->req.p.http;
CURLcode result = CURLE_OK;
(void)conn;
(void)stream_id;
@@ -1166,6 +1152,7 @@ static nghttp3_conn_callbacks ngh3_callbacks = {
cb_h3_send_stop_sending,
NULL, /* push_stream */
NULL, /* end_stream */
+ NULL, /* reset_stream */
};
static int init_ngh3_conn(struct quicsocket *qs)
@@ -1255,7 +1242,7 @@ static ssize_t ngh3_stream_recv(struct connectdata *conn,
CURLcode *curlcode)
{
curl_socket_t sockfd = conn->sock[sockindex];
- struct HTTP *stream = conn->data->req.protop;
+ struct HTTP *stream = conn->data->req.p.http;
struct quicsocket *qs = conn->quic;
if(!stream->memlen) {
@@ -1313,7 +1300,7 @@ static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id,
void *stream_user_data)
{
struct Curl_easy *data = stream_user_data;
- struct HTTP *stream = data->req.protop;
+ struct HTTP *stream = data->req.p.http;
(void)conn;
(void)stream_id;
(void)user_data;
@@ -1335,7 +1322,7 @@ static ssize_t cb_h3_readfunction(nghttp3_conn *conn, int64_t stream_id,
{
struct Curl_easy *data = stream_user_data;
size_t nread;
- struct HTTP *stream = data->req.protop;
+ struct HTTP *stream = data->req.p.http;
(void)conn;
(void)stream_id;
(void)user_data;
@@ -1398,7 +1385,7 @@ static ssize_t cb_h3_readfunction(nghttp3_conn *conn, int64_t stream_id,
static CURLcode http_request(struct connectdata *conn, const void *mem,
size_t len)
{
- struct HTTP *stream = conn->data->req.protop;
+ struct HTTP *stream = conn->data->req.p.http;
size_t nheader;
size_t i;
size_t authority_idx;
@@ -1573,7 +1560,7 @@ static CURLcode http_request(struct connectdata *conn, const void *mem,
if(acc > MAX_ACC) {
infof(data, "http_request: Warning: The cumulative length of all "
- "headers exceeds %zu bytes and that could cause the "
+ "headers exceeds %d bytes and that could cause the "
"stream to be rejected.\n", MAX_ACC);
}
}
@@ -1641,7 +1628,7 @@ static ssize_t ngh3_stream_send(struct connectdata *conn,
ssize_t sent;
struct quicsocket *qs = conn->quic;
curl_socket_t sockfd = conn->sock[sockindex];
- struct HTTP *stream = conn->data->req.protop;
+ struct HTTP *stream = conn->data->req.p.http;
if(!stream->h3req) {
CURLcode result = http_request(conn, mem, len);
@@ -1718,7 +1705,8 @@ CURLcode Curl_quic_is_connected(struct connectdata *conn,
}
-static CURLcode ng_process_ingress(struct connectdata *conn, int sockfd,
+static CURLcode ng_process_ingress(struct connectdata *conn,
+ curl_socket_t sockfd,
struct quicsocket *qs)
{
ssize_t recvd;
@@ -1729,10 +1717,11 @@ static CURLcode ng_process_ingress(struct connectdata *conn, int sockfd,
socklen_t remote_addrlen;
ngtcp2_path path;
ngtcp2_tstamp ts = timestamp();
+ ngtcp2_pkt_info pi = { 0 };
for(;;) {
remote_addrlen = sizeof(remote_addr);
- while((recvd = recvfrom(sockfd, buf, bufsize, 0,
+ while((recvd = recvfrom(sockfd, (char *)buf, bufsize, 0,
(struct sockaddr *)&remote_addr,
&remote_addrlen)) == -1 &&
SOCKERRNO == EINTR)
@@ -1741,16 +1730,16 @@ static CURLcode ng_process_ingress(struct connectdata *conn, int sockfd,
if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK)
break;
- failf(conn->data, "ngtcp2: recvfrom() unexpectedly returned %d", recvd);
+ failf(conn->data, "ngtcp2: recvfrom() unexpectedly returned %zd", recvd);
return CURLE_RECV_ERROR;
}
- ngtcp2_addr_init(&path.local, &qs->local_addr,
+ ngtcp2_addr_init(&path.local, (struct sockaddr *)&qs->local_addr,
qs->local_addrlen, NULL);
ngtcp2_addr_init(&path.remote, (struct sockaddr *)&remote_addr,
remote_addrlen, NULL);
- rv = ngtcp2_conn_read_pkt(qs->qconn, &path, buf, recvd, ts);
+ rv = ngtcp2_conn_read_pkt(qs->qconn, &path, &pi, buf, recvd, ts);
if(rv != 0) {
/* TODO Send CONNECTION_CLOSE if possible */
return CURLE_RECV_ERROR;
@@ -1779,7 +1768,7 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
nghttp3_vec vec[16];
ssize_t ndatalen;
- switch(qs->local_addr.sa_family) {
+ switch(qs->local_addr.ss_family) {
case AF_INET:
pktlen = NGTCP2_MAX_PKTLEN_IPV4;
break;
@@ -1815,7 +1804,7 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
uint32_t flags = NGTCP2_WRITE_STREAM_FLAG_MORE |
(fin ? NGTCP2_WRITE_STREAM_FLAG_FIN : 0);
outlen =
- ngtcp2_conn_writev_stream(qs->qconn, &ps.path,
+ ngtcp2_conn_writev_stream(qs->qconn, &ps.path, NULL,
out, pktlen, &ndatalen,
flags, stream_id,
(const ngtcp2_vec *)vec, veccnt, ts);
@@ -1860,7 +1849,8 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
}
}
if(outlen < 0) {
- outlen = ngtcp2_conn_write_pkt(qs->qconn, &ps.path, out, pktlen, ts);
+ outlen = ngtcp2_conn_write_pkt(qs->qconn, &ps.path, NULL,
+ out, pktlen, ts);
if(outlen < 0) {
failf(conn->data, "ngtcp2_conn_write_pkt returned error: %s\n",
ngtcp2_strerror((int)outlen));
@@ -1871,7 +1861,7 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
}
memcpy(&remote_addr, ps.path.remote.addr, ps.path.remote.addrlen);
- while((sent = send(sockfd, out, outlen, 0)) == -1 &&
+ while((sent = send(sockfd, (const char *)out, outlen, 0)) == -1 &&
SOCKERRNO == EINTR)
;
@@ -1909,7 +1899,7 @@ CURLcode Curl_quic_done_sending(struct connectdata *conn)
{
if(conn->handler == &Curl_handler_http3) {
/* only for HTTP/3 transfers */
- struct HTTP *stream = conn->data->req.protop;
+ struct HTTP *stream = conn->data->req.p.http;
struct quicsocket *qs = conn->quic;
stream->upload_done = TRUE;
(void)nghttp3_conn_resume_stream(qs->h3conn, stream->stream3_id);
@@ -1926,7 +1916,7 @@ void Curl_quic_done(struct Curl_easy *data, bool premature)
(void)premature;
if(data->conn->handler == &Curl_handler_http3) {
/* only for HTTP/3 transfers */
- struct HTTP *stream = data->req.protop;
+ struct HTTP *stream = data->req.p.http;
Curl_dyn_free(&stream->overflow);
}
}
@@ -1941,7 +1931,7 @@ bool Curl_quic_data_pending(const struct Curl_easy *data)
buffer and allocated an overflow buffer. Since it's possible that
there's no more data coming on the socket, we need to keep reading
until the overflow buffer is empty. */
- const struct HTTP *stream = data->req.protop;
+ const struct HTTP *stream = data->req.p.http;
return Curl_dyn_len(&stream->overflow) > 0;
}
diff --git a/lib/vquic/ngtcp2.h b/lib/vquic/ngtcp2.h
index afdd01b7c..c6d4d12e6 100644
--- a/lib/vquic/ngtcp2.h
+++ b/lib/vquic/ngtcp2.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -58,7 +58,7 @@ struct quicsocket {
struct quic_handshake crypto_data[3];
/* the last TLS alert description generated by the local endpoint */
uint8_t tls_alert;
- struct sockaddr local_addr;
+ struct sockaddr_storage local_addr;
socklen_t local_addrlen;
nghttp3_conn *h3conn;
diff --git a/lib/vquic/quiche.c b/lib/vquic/quiche.c
index fd9cb8bd3..d0d150e39 100644
--- a/lib/vquic/quiche.c
+++ b/lib/vquic/quiche.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -89,8 +89,17 @@ static int quiche_perform_getsock(const struct connectdata *conn,
return quiche_getsock((struct connectdata *)conn, socks);
}
-static CURLcode qs_disconnect(struct quicsocket *qs)
+static CURLcode qs_disconnect(struct connectdata *conn,
+ struct quicsocket *qs)
{
+ if(qs->conn) {
+ (void)quiche_conn_close(qs->conn, TRUE, 0, NULL, 0);
+ /* flushing the egress is not a failsafe way to deliver all the
+ outstanding packets, but we also don't want to get stuck here... */
+ (void)flush_egress(conn, qs->sockfd, qs);
+ quiche_conn_free(qs->conn);
+ qs->conn = NULL;
+ }
if(qs->h3config)
quiche_h3_config_free(qs->h3config);
if(qs->h3c)
@@ -99,10 +108,6 @@ static CURLcode qs_disconnect(struct quicsocket *qs)
quiche_config_free(qs->cfg);
qs->cfg = NULL;
}
- if(qs->conn) {
- quiche_conn_free(qs->conn);
- qs->conn = NULL;
- }
return CURLE_OK;
}
@@ -111,14 +116,14 @@ static CURLcode quiche_disconnect(struct connectdata *conn,
{
struct quicsocket *qs = conn->quic;
(void)dead_connection;
- return qs_disconnect(qs);
+ return qs_disconnect(conn, qs);
}
void Curl_quic_disconnect(struct connectdata *conn,
int tempindex)
{
if(conn->transport == TRNSPRT_QUIC)
- qs_disconnect(&conn->hequic[tempindex]);
+ qs_disconnect(conn, &conn->hequic[tempindex]);
}
static unsigned int quiche_conncheck(struct connectdata *conn,
@@ -131,7 +136,7 @@ static unsigned int quiche_conncheck(struct connectdata *conn,
static CURLcode quiche_do(struct connectdata *conn, bool *done)
{
- struct HTTP *stream = conn->data->req.protop;
+ struct HTTP *stream = conn->data->req.p.http;
stream->h3req = FALSE; /* not sent */
return Curl_http(conn, done);
}
@@ -154,6 +159,7 @@ static const struct Curl_handler Curl_handler_http3 = {
quiche_conncheck, /* connection_check */
PORT_HTTP, /* defport */
CURLPROTO_HTTPS, /* protocol */
+ CURLPROTO_HTTP, /* family */
PROTOPT_SSL | PROTOPT_STREAM /* flags */
};
@@ -186,6 +192,7 @@ CURLcode Curl_quic_connect(struct connectdata *conn, curl_socket_t sockfd,
(void)addr;
(void)addrlen;
+ qs->sockfd = sockfd;
qs->cfg = quiche_config_new(QUICHE_PROTOCOL_VERSION);
if(!qs->cfg) {
failf(data, "can't create quiche config");
@@ -336,7 +343,7 @@ CURLcode Curl_quic_is_connected(struct connectdata *conn, int sockindex,
return result;
error:
- qs_disconnect(qs);
+ qs_disconnect(conn, qs);
return result;
}
@@ -357,7 +364,7 @@ static CURLcode process_ingress(struct connectdata *conn, int sockfd,
break;
if(recvd < 0) {
- failf(conn->data, "quiche: recv() unexpectedly returned %d "
+ failf(conn->data, "quiche: recv() unexpectedly returned %zd "
"(errno: %d, socket %d)", recvd, SOCKERRNO, sockfd);
return CURLE_RECV_ERROR;
}
@@ -367,7 +374,7 @@ static CURLcode process_ingress(struct connectdata *conn, int sockfd,
break;
if(recvd < 0) {
- failf(conn->data, "quiche_conn_recv() == %d", recvd);
+ failf(conn->data, "quiche_conn_recv() == %zd", recvd);
return CURLE_RECV_ERROR;
}
} while(1);
@@ -383,7 +390,7 @@ static CURLcode flush_egress(struct connectdata *conn, int sockfd,
struct quicsocket *qs)
{
ssize_t sent;
- static uint8_t out[1200];
+ uint8_t out[1200];
int64_t timeout_ns;
do {
@@ -460,7 +467,7 @@ static ssize_t h3_stream_recv(struct connectdata *conn,
int rc;
struct h3h1header headers;
struct Curl_easy *data = conn->data;
- struct HTTP *stream = data->req.protop;
+ struct HTTP *stream = data->req.p.http;
headers.dest = buf;
headers.destlen = buffersize;
headers.nlen = 0;
@@ -548,7 +555,7 @@ static ssize_t h3_stream_send(struct connectdata *conn,
ssize_t sent;
struct quicsocket *qs = conn->quic;
curl_socket_t sockfd = conn->sock[sockindex];
- struct HTTP *stream = conn->data->req.protop;
+ struct HTTP *stream = conn->data->req.p.http;
if(!stream->h3req) {
CURLcode result = http_request(conn, mem, len);
@@ -596,7 +603,7 @@ static CURLcode http_request(struct connectdata *conn, const void *mem,
{
/*
*/
- struct HTTP *stream = conn->data->req.protop;
+ struct HTTP *stream = conn->data->req.p.http;
size_t nheader;
size_t i;
size_t authority_idx;
@@ -761,7 +768,7 @@ static CURLcode http_request(struct connectdata *conn, const void *mem,
if(acc > MAX_ACC) {
infof(data, "http_request: Warning: The cumulative length of all "
- "headers exceeds %zu bytes and that could cause the "
+ "headers exceeds %d bytes and that could cause the "
"stream to be rejected.\n", MAX_ACC);
}
}
@@ -824,7 +831,7 @@ CURLcode Curl_quic_done_sending(struct connectdata *conn)
if(conn->handler == &Curl_handler_http3) {
/* only for HTTP/3 transfers */
ssize_t sent;
- struct HTTP *stream = conn->data->req.protop;
+ struct HTTP *stream = conn->data->req.p.http;
struct quicsocket *qs = conn->quic;
fprintf(stderr, "!!! Curl_quic_done_sending\n");
stream->upload_done = TRUE;
diff --git a/lib/vquic/quiche.h b/lib/vquic/quiche.h
index c8d1837b5..d311e9988 100644
--- a/lib/vquic/quiche.h
+++ b/lib/vquic/quiche.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -41,6 +41,7 @@ struct quicsocket {
quiche_h3_conn *h3c;
quiche_h3_config *h3config;
uint8_t scid[QUICHE_MAX_CONN_ID_LEN];
+ curl_socket_t sockfd;
uint32_t version;
};
diff --git a/lib/vquic/vquic.c b/lib/vquic/vquic.c
index aae8e0951..7c0cc6df2 100644
--- a/lib/vquic/vquic.c
+++ b/lib/vquic/vquic.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vquic/vquic.h b/lib/vquic/vquic.h
index ecff0edf4..eb8a893d9 100644
--- a/lib/vquic/vquic.h
+++ b/lib/vquic/vquic.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c
index 434904ff9..f4e3d4b3c 100644
--- a/lib/vssh/libssh.c
+++ b/lib/vssh/libssh.c
@@ -12,7 +12,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -158,6 +158,7 @@ const struct Curl_handler Curl_handler_scp = {
ZERO_NULL, /* connection_check */
PORT_SSH, /* defport */
CURLPROTO_SCP, /* protocol */
+ CURLPROTO_SCP, /* family */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */
};
@@ -183,6 +184,7 @@ const struct Curl_handler Curl_handler_sftp = {
ZERO_NULL, /* connection_check */
PORT_SSH, /* defport */
CURLPROTO_SFTP, /* protocol */
+ CURLPROTO_SFTP, /* family */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
| PROTOPT_NOURLQUERY /* flags */
};
@@ -662,7 +664,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct SSHPROTO *protop = data->req.protop;
+ struct SSHPROTO *protop = data->req.p.ssh;
struct ssh_conn *sshc = &conn->proto.sshc;
curl_socket_t sock = conn->sock[FIRSTSOCKET];
int rc = SSH_NO_ERROR, err;
@@ -1430,11 +1432,8 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
data->req.bytecount += sshc->readdir_len + 1;
/* output debug output if that is requested */
- if(data->set.verbose) {
- Curl_debug(data, CURLINFO_DATA_OUT,
- (char *)sshc->readdir_filename,
- sshc->readdir_len);
- }
+ Curl_debug(data, CURLINFO_DATA_OUT, (char *)sshc->readdir_filename,
+ sshc->readdir_len);
}
else {
sshc->readdir_currLen = strlen(sshc->readdir_longentry);
@@ -1546,12 +1545,9 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
sshc->readdir_currLen);
if(!result) {
-
/* output debug output if that is requested */
- if(data->set.verbose) {
- Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
- sshc->readdir_currLen);
- }
+ Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
+ sshc->readdir_currLen);
data->req.bytecount += sshc->readdir_currLen;
}
Curl_safefree(sshc->readdir_line);
@@ -2129,7 +2125,7 @@ static CURLcode myssh_setup_connection(struct connectdata *conn)
{
struct SSHPROTO *ssh;
- conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
+ conn->data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO));
if(!ssh)
return CURLE_OUT_OF_MEMORY;
@@ -2152,7 +2148,7 @@ static CURLcode myssh_connect(struct connectdata *conn, bool *done)
int rc;
/* initialize per-handle data if not already */
- if(!data->req.protop)
+ if(!data->req.p.ssh)
myssh_setup_connection(conn);
/* We default to persistent connections. We set this already in this connect
@@ -2353,7 +2349,7 @@ static CURLcode scp_disconnect(struct connectdata *conn,
static CURLcode myssh_done(struct connectdata *conn, CURLcode status)
{
CURLcode result = CURLE_OK;
- struct SSHPROTO *protop = conn->data->req.protop;
+ struct SSHPROTO *protop = conn->data->req.p.ssh;
if(!status) {
/* run the state-machine */
@@ -2606,7 +2602,7 @@ static void sftp_quote(struct connectdata *conn)
{
const char *cp;
struct Curl_easy *data = conn->data;
- struct SSHPROTO *protop = data->req.protop;
+ struct SSHPROTO *protop = data->req.p.ssh;
struct ssh_conn *sshc = &conn->proto.sshc;
CURLcode result;
@@ -2636,10 +2632,9 @@ static void sftp_quote(struct connectdata *conn)
sshc->nextstate = SSH_NO_STATE;
return;
}
- if(data->set.verbose) {
- Curl_debug(data, CURLINFO_HEADER_OUT, (char *) "PWD\n", 4);
- Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
- }
+ Curl_debug(data, CURLINFO_HEADER_OUT, (char *) "PWD\n", 4);
+ Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
+
/* this sends an FTP-like "header" to the header callback so that the
current directory can be read very similar to how it is read when
using ordinary FTP. */
@@ -2692,7 +2687,9 @@ static void sftp_quote(struct connectdata *conn)
*/
if(strncasecompare(cmd, "chgrp ", 6) ||
strncasecompare(cmd, "chmod ", 6) ||
- strncasecompare(cmd, "chown ", 6)) {
+ strncasecompare(cmd, "chown ", 6) ||
+ strncasecompare(cmd, "atime ", 6) ||
+ strncasecompare(cmd, "mtime ", 6)) {
/* attribute change */
/* sshc->quote_path1 contains the mode to set */
@@ -2702,7 +2699,7 @@ static void sftp_quote(struct connectdata *conn)
if(result == CURLE_OUT_OF_MEMORY)
failf(data, "Out of memory");
else
- failf(data, "Syntax error in chgrp/chmod/chown: "
+ failf(data, "Syntax error in chgrp/chmod/chown/atime/mtime: "
"Bad second parameter");
Curl_safefree(sshc->quote_path1);
state(conn, SSH_SFTP_CLOSE);
@@ -2863,6 +2860,34 @@ static void sftp_quote_stat(struct connectdata *conn)
}
sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID;
}
+ else if(strncasecompare(cmd, "atime", 5)) {
+ time_t date = Curl_getdate_capped(sshc->quote_path1);
+ if(date == -1) {
+ Curl_safefree(sshc->quote_path1);
+ Curl_safefree(sshc->quote_path2);
+ failf(data, "Syntax error: incorrect access date format");
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = CURLE_QUOTE_ERROR;
+ return;
+ }
+ sshc->quote_attrs->atime = (uint32_t)date;
+ sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_ACMODTIME;
+ }
+ else if(strncasecompare(cmd, "mtime", 5)) {
+ time_t date = Curl_getdate_capped(sshc->quote_path1);
+ if(date == -1) {
+ Curl_safefree(sshc->quote_path1);
+ Curl_safefree(sshc->quote_path2);
+ failf(data, "Syntax error: incorrect modification date format");
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = CURLE_QUOTE_ERROR;
+ return;
+ }
+ sshc->quote_attrs->mtime = (uint32_t)date;
+ sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_ACMODTIME;
+ }
/* Now send the completed structure... */
state(conn, SSH_SFTP_QUOTE_SETSTAT);
diff --git a/lib/vssh/libssh2.c b/lib/vssh/libssh2.c
index 87cbe916e..f5eb1dd39 100644
--- a/lib/vssh/libssh2.c
+++ b/lib/vssh/libssh2.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -150,6 +150,7 @@ const struct Curl_handler Curl_handler_scp = {
ZERO_NULL, /* connection_check */
PORT_SSH, /* defport */
CURLPROTO_SCP, /* protocol */
+ CURLPROTO_SCP, /* family */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
| PROTOPT_NOURLQUERY /* flags */
};
@@ -177,6 +178,7 @@ const struct Curl_handler Curl_handler_sftp = {
ZERO_NULL, /* connection_check */
PORT_SSH, /* defport */
CURLPROTO_SFTP, /* protocol */
+ CURLPROTO_SFTP, /* family */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
| PROTOPT_NOURLQUERY /* flags */
};
@@ -442,6 +444,7 @@ static CURLcode ssh_knownhost(struct connectdata *conn)
if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
/* we're asked to verify the host against a file */
struct ssh_conn *sshc = &conn->proto.sshc;
+ struct libssh2_knownhost *host = NULL;
int rc;
int keytype;
size_t keylen;
@@ -456,7 +459,6 @@ static CURLcode ssh_knownhost(struct connectdata *conn)
* What host name does OpenSSH store in its file if an IDN name is
* used?
*/
- struct libssh2_knownhost *host;
enum curl_khmatch keymatch;
curl_sshkeycallback func =
data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
@@ -568,7 +570,13 @@ static CURLcode ssh_knownhost(struct connectdata *conn)
/* DEFER means bail out but keep the SSH_HOSTKEY state */
result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
break;
+ case CURLKHSTAT_FINE_REPLACE:
+ /* remove old host+key that doesn't match */
+ if(host)
+ libssh2_knownhost_del(sshc->kh, host);
+ /*FALLTHROUGH*/
case CURLKHSTAT_FINE:
+ /*FALLTHROUGH*/
case CURLKHSTAT_FINE_ADD_TO_FILE:
/* proceed */
if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
@@ -583,7 +591,8 @@ static CURLcode ssh_knownhost(struct connectdata *conn)
if(addrc)
infof(data, "Warning adding the known host %s failed!\n",
conn->host.name);
- else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
+ else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE ||
+ rc == CURLKHSTAT_FINE_REPLACE) {
/* now we write the entire in-memory list of known hosts to the
known_hosts file */
int wrc =
@@ -789,7 +798,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
- struct SSHPROTO *sftp_scp = data->req.protop;
+ struct SSHPROTO *sftp_scp = data->req.p.ssh;
struct ssh_conn *sshc = &conn->proto.sshc;
curl_socket_t sock = conn->sock[FIRSTSOCKET];
int rc = LIBSSH2_ERROR_NONE;
@@ -814,6 +823,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
result = ssh_force_knownhost_key_type(conn);
if(result) {
state(conn, SSH_SESSION_FREE);
+ sshc->actualcode = result;
break;
}
@@ -1255,7 +1265,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
a time-out or similar */
result = CURLE_SSH;
sshc->actualcode = result;
- DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
+ DEBUGF(infof(data, "error = %lu makes libcurl = %d\n",
sftperr, (int)result));
state(conn, SSH_STOP);
break;
@@ -1333,10 +1343,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
sshc->nextstate = SSH_NO_STATE;
break;
}
- if(data->set.verbose) {
- Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4);
- Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
- }
+ Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4);
+ Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
+
/* this sends an FTP-like "header" to the header callback so that the
current directory can be read very similar to how it is read when
using ordinary FTP. */
@@ -1390,7 +1399,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
*/
if(strncasecompare(cmd, "chgrp ", 6) ||
strncasecompare(cmd, "chmod ", 6) ||
- strncasecompare(cmd, "chown ", 6) ) {
+ strncasecompare(cmd, "chown ", 6) ||
+ strncasecompare(cmd, "atime ", 6) ||
+ strncasecompare(cmd, "mtime ", 6)) {
/* attribute change */
/* sshc->quote_path1 contains the mode to set */
@@ -1587,6 +1598,34 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
}
}
+ else if(strncasecompare(cmd, "atime", 5)) {
+ time_t date = Curl_getdate_capped(sshc->quote_path1);
+ if(date == -1) {
+ Curl_safefree(sshc->quote_path1);
+ Curl_safefree(sshc->quote_path2);
+ failf(data, "Syntax error: incorrect access date format");
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = CURLE_QUOTE_ERROR;
+ break;
+ }
+ sshc->quote_attrs.atime = (unsigned long)date;
+ sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_ACMODTIME;
+ }
+ else if(strncasecompare(cmd, "mtime", 5)) {
+ time_t date = Curl_getdate_capped(sshc->quote_path1);
+ if(date == -1) {
+ Curl_safefree(sshc->quote_path1);
+ Curl_safefree(sshc->quote_path2);
+ failf(data, "Syntax error: incorrect modification date format");
+ state(conn, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = CURLE_QUOTE_ERROR;
+ break;
+ }
+ sshc->quote_attrs.mtime = (unsigned long)date;
+ sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_ACMODTIME;
+ }
/* Now send the completed structure... */
state(conn, SSH_SFTP_QUOTE_SETSTAT);
@@ -1906,7 +1945,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
sshc->actualcode = CURLE_SSH;
sftperr = LIBSSH2_FX_OK;
}
- failf(data, "Upload failed: %s (%d/%d)",
+ failf(data, "Upload failed: %s (%lu/%d)",
sftperr != LIBSSH2_FX_OK ?
sftp_libssh2_strerror(sftperr):"ssh error",
sftperr, rc);
@@ -2127,11 +2166,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
data->req.bytecount += readdir_len + 1;
/* output debug output if that is requested */
- if(data->set.verbose) {
- Curl_debug(data, CURLINFO_DATA_IN, sshc->readdir_filename,
- readdir_len);
- Curl_debug(data, CURLINFO_DATA_IN, (char *)"\n", 1);
- }
+ Curl_debug(data, CURLINFO_DATA_IN, sshc->readdir_filename,
+ readdir_len);
+ Curl_debug(data, CURLINFO_DATA_IN, (char *)"\n", 1);
}
else {
result = Curl_dyn_add(&sshc->readdir, sshc->readdir_longentry);
@@ -2212,13 +2249,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
Curl_dyn_len(&sshc->readdir));
if(!result) {
-
/* output debug output if that is requested */
- if(data->set.verbose) {
- Curl_debug(data, CURLINFO_DATA_IN,
- Curl_dyn_ptr(&sshc->readdir),
- Curl_dyn_len(&sshc->readdir));
- }
+ Curl_debug(data, CURLINFO_DATA_IN,
+ Curl_dyn_ptr(&sshc->readdir),
+ Curl_dyn_len(&sshc->readdir));
data->req.bytecount += Curl_dyn_len(&sshc->readdir);
}
if(result) {
@@ -2847,7 +2881,6 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
static int ssh_perform_getsock(const struct connectdata *conn,
curl_socket_t *sock)
{
-#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
int bitmap = GETSOCK_BLANK;
sock[0] = conn->sock[FIRSTSOCKET];
@@ -2859,11 +2892,6 @@ static int ssh_perform_getsock(const struct connectdata *conn,
bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
return bitmap;
-#else
- /* if we don't know the direction we can use the generic *_getsock()
- function even for the protocol_connect and doing states */
- return Curl_single_getsock(conn, sock);
-#endif
}
/* Generic function called by the multi interface to figure out what socket(s)
@@ -2871,20 +2899,11 @@ static int ssh_perform_getsock(const struct connectdata *conn,
static int ssh_getsock(struct connectdata *conn,
curl_socket_t *sock)
{
-#ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
- (void)conn;
- (void)sock;
- /* if we don't know any direction we can just play along as we used to and
- not provide any sensible info */
- return GETSOCK_BLANK;
-#else
/* if we know the direction we can use the generic *_getsock() function even
for the protocol_connect and doing states */
return ssh_perform_getsock(conn, sock);
-#endif
}
-#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
/*
* When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
* function is used to figure out in what direction and stores this info so
@@ -2909,10 +2928,6 @@ static void ssh_block2waitfor(struct connectdata *conn, bool block)
the original set */
conn->waitfor = sshc->orig_waitfor;
}
-#else
- /* no libssh2 directional support so we simply don't know */
-#define ssh_block2waitfor(x,y) Curl_nop_stmt
-#endif
/* called repeatedly until done from multi.c */
static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
@@ -2961,7 +2976,6 @@ static CURLcode ssh_block_statemach(struct connectdata *conn,
return CURLE_OPERATION_TIMEDOUT;
}
-#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
if(block) {
int dir = libssh2_session_block_directions(sshc->ssh_session);
curl_socket_t sock = conn->sock[FIRSTSOCKET];
@@ -2975,8 +2989,6 @@ static CURLcode ssh_block_statemach(struct connectdata *conn,
(void)Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write,
left>1000?1000:left);
}
-#endif
-
}
return result;
@@ -2989,7 +3001,7 @@ static CURLcode ssh_setup_connection(struct connectdata *conn)
{
struct SSHPROTO *ssh;
- conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
+ conn->data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO));
if(!ssh)
return CURLE_OUT_OF_MEMORY;
@@ -2999,6 +3011,54 @@ static CURLcode ssh_setup_connection(struct connectdata *conn)
static Curl_recv scp_recv, sftp_recv;
static Curl_send scp_send, sftp_send;
+#ifndef CURL_DISABLE_PROXY
+static ssize_t ssh_tls_recv(libssh2_socket_t sock, void *buffer,
+ size_t length, int flags, void **abstract)
+{
+ struct connectdata *conn = (struct connectdata *)*abstract;
+ ssize_t nread;
+ CURLcode result;
+ Curl_recv *backup = conn->recv[0];
+ struct ssh_conn *ssh = &conn->proto.sshc;
+ (void)flags;
+
+ /* swap in the TLS reader function for this call only, and then swap back
+ the SSH one again */
+ conn->recv[0] = ssh->tls_recv;
+ result = Curl_read(conn, sock, buffer, length, &nread);
+ conn->recv[0] = backup;
+ if(result == CURLE_AGAIN)
+ return -EAGAIN; /* magic return code for libssh2 */
+ else if(result)
+ return -1; /* generic error */
+ Curl_debug(conn->data, CURLINFO_DATA_IN, (char *)buffer, (size_t)nread);
+ return nread;
+}
+
+static ssize_t ssh_tls_send(libssh2_socket_t sock, const void *buffer,
+ size_t length, int flags, void **abstract)
+{
+ struct connectdata *conn = (struct connectdata *)*abstract;
+ ssize_t nwrite;
+ CURLcode result;
+ Curl_send *backup = conn->send[0];
+ struct ssh_conn *ssh = &conn->proto.sshc;
+ (void)flags;
+
+ /* swap in the TLS writer function for this call only, and then swap back
+ the SSH one again */
+ conn->send[0] = ssh->tls_send;
+ result = Curl_write(conn, sock, buffer, length, &nwrite);
+ conn->send[0] = backup;
+ if(result == CURLE_AGAIN)
+ return -EAGAIN; /* magic return code for libssh2 */
+ else if(result)
+ return -1; /* error */
+ Curl_debug(conn->data, CURLINFO_DATA_OUT, (char *)buffer, (size_t)nwrite);
+ return nwrite;
+}
+#endif
+
/*
* Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
* do protocol-specific actions at connect-time.
@@ -3013,21 +3073,13 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done)
struct Curl_easy *data = conn->data;
/* initialize per-handle data if not already */
- if(!data->req.protop)
+ if(!data->req.p.ssh)
ssh_setup_connection(conn);
/* We default to persistent connections. We set this already in this connect
function to make the re-use checks properly be able to check this bit. */
connkeep(conn, "SSH default");
- if(conn->handler->protocol & CURLPROTO_SCP) {
- conn->recv[FIRSTSOCKET] = scp_recv;
- conn->send[FIRSTSOCKET] = scp_send;
- }
- else {
- conn->recv[FIRSTSOCKET] = sftp_recv;
- conn->send[FIRSTSOCKET] = sftp_send;
- }
ssh = &conn->proto.sshc;
#ifdef CURL_LIBSSH2_DEBUG
@@ -3048,6 +3100,61 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done)
return CURLE_FAILED_INIT;
}
+#ifndef CURL_DISABLE_PROXY
+ if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) {
+ /*
+ * This crazy union dance is here to avoid assigning a void pointer a
+ * function pointer as it is invalid C. The problem is of course that
+ * libssh2 has such an API...
+ */
+ union receive {
+ void *recvp;
+ ssize_t (*recvptr)(libssh2_socket_t, void *, size_t, int, void **);
+ };
+ union transfer {
+ void *sendp;
+ ssize_t (*sendptr)(libssh2_socket_t, const void *, size_t, int, void **);
+ };
+ union receive sshrecv;
+ union transfer sshsend;
+
+ sshrecv.recvptr = ssh_tls_recv;
+ sshsend.sendptr = ssh_tls_send;
+
+ infof(data, "Uses HTTPS proxy!\n");
+ /*
+ Setup libssh2 callbacks to make it read/write TLS from the socket.
+
+ ssize_t
+ recvcb(libssh2_socket_t sock, void *buffer, size_t length,
+ int flags, void **abstract);
+
+ ssize_t
+ sendcb(libssh2_socket_t sock, const void *buffer, size_t length,
+ int flags, void **abstract);
+
+ */
+ libssh2_session_callback_set(ssh->ssh_session,
+ LIBSSH2_CALLBACK_RECV, sshrecv.recvp);
+ libssh2_session_callback_set(ssh->ssh_session,
+ LIBSSH2_CALLBACK_SEND, sshsend.sendp);
+
+ /* Store the underlying TLS recv/send function pointers to be used when
+ reading from the proxy */
+ ssh->tls_recv = conn->recv[FIRSTSOCKET];
+ ssh->tls_send = conn->send[FIRSTSOCKET];
+ }
+
+#endif /* CURL_DISABLE_PROXY */
+ if(conn->handler->protocol & CURLPROTO_SCP) {
+ conn->recv[FIRSTSOCKET] = scp_recv;
+ conn->send[FIRSTSOCKET] = scp_send;
+ }
+ else {
+ conn->recv[FIRSTSOCKET] = sftp_recv;
+ conn->send[FIRSTSOCKET] = sftp_send;
+ }
+
if(data->set.ssh_compression) {
#if LIBSSH2_VERSION_NUM >= 0x010208
if(libssh2_session_flag(ssh->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0)
@@ -3192,7 +3299,7 @@ static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
{
CURLcode result = CURLE_OK;
- struct SSHPROTO *sftp_scp = conn->data->req.protop;
+ struct SSHPROTO *sftp_scp = conn->data->req.p.ssh;
if(!status) {
/* run the state-machine */
diff --git a/lib/vssh/ssh.h b/lib/vssh/ssh.h
index 9e49993e9..377337031 100644
--- a/lib/vssh/ssh.h
+++ b/lib/vssh/ssh.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -182,6 +182,12 @@ struct ssh_conn {
LIBSSH2_SFTP *sftp_session; /* SFTP handle */
LIBSSH2_SFTP_HANDLE *sftp_handle;
+#ifndef CURL_DISABLE_PROXY
+ /* for HTTPS proxy storage */
+ Curl_recv *tls_recv;
+ Curl_send *tls_send;
+#endif
+
#ifdef HAVE_LIBSSH2_AGENT_API
LIBSSH2_AGENT *ssh_agent; /* proxy to ssh-agent/pageant */
struct libssh2_agent_publickey *sshagent_identity,
diff --git a/lib/vssh/wolfssh.c b/lib/vssh/wolfssh.c
index dcbbab6c3..b0dfb2047 100644
--- a/lib/vssh/wolfssh.c
+++ b/lib/vssh/wolfssh.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -322,7 +322,7 @@ static CURLcode wssh_setup_connection(struct connectdata *conn)
{
struct SSHPROTO *ssh;
- conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
+ conn->data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO));
if(!ssh)
return CURLE_OUT_OF_MEMORY;
@@ -356,7 +356,7 @@ static CURLcode wssh_connect(struct connectdata *conn, bool *done)
int rc;
/* initialize per-handle data if not already */
- if(!data->req.protop)
+ if(!data->req.p.ssh)
wssh_setup_connection(conn);
/* We default to persistent connections. We set this already in this connect
@@ -429,7 +429,7 @@ static CURLcode wssh_statemach_act(struct connectdata *conn, bool *block)
CURLcode result = CURLE_OK;
struct ssh_conn *sshc = &conn->proto.sshc;
struct Curl_easy *data = conn->data;
- struct SSHPROTO *sftp_scp = data->req.protop;
+ struct SSHPROTO *sftp_scp = data->req.p.ssh;
WS_SFTPNAME *name;
int rc = 0;
*block = FALSE; /* we're not blocking by default */
@@ -1027,7 +1027,7 @@ static CURLcode wssh_block_statemach(struct connectdata *conn,
static CURLcode wssh_done(struct connectdata *conn, CURLcode status)
{
CURLcode result = CURLE_OK;
- struct SSHPROTO *sftp_scp = conn->data->req.protop;
+ struct SSHPROTO *sftp_scp = conn->data->req.p.ssh;
if(!status) {
/* run the state-machine */
diff --git a/lib/vssh/wolfssh.h b/lib/vssh/wolfssh.h
index a9b9a3b09..7b6ac489a 100644
--- a/lib/vssh/wolfssh.h
+++ b/lib/vssh/wolfssh.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/bearssl.c b/lib/vtls/bearssl.c
index 44e7406e8..b0c3dc2f0 100644
--- a/lib/vtls/bearssl.c
+++ b/lib/vtls/bearssl.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/bearssl.h b/lib/vtls/bearssl.h
index 5f94922b9..d72b7d0e2 100644
--- a/lib/vtls/bearssl.h
+++ b/lib/vtls/bearssl.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2019, Michael Forney, <mforney@mforney.org>
+ * Copyright (C) 2019 - 2020, Michael Forney, <mforney@mforney.org>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/gskit.c b/lib/vtls/gskit.c
index 2998a8eb4..9a42869d7 100644
--- a/lib/vtls/gskit.c
+++ b/lib/vtls/gskit.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -705,7 +705,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
int rc;
const char * const keyringfile = SSL_CONN_CONFIG(CAfile);
const char * const keyringpwd = SSL_SET_OPTION(key_passwd);
- const char * const keyringlabel = SSL_SET_OPTION(cert);
+ const char * const keyringlabel = SSL_SET_OPTION(primary.clientcert);
const long int ssl_version = SSL_CONN_CONFIG(version);
const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
const char * const hostname = SSL_IS_PROXY()? conn->http_proxy.host.name:
diff --git a/lib/vtls/gskit.h b/lib/vtls/gskit.h
index b06b5e17d..202df7e07 100644
--- a/lib/vtls/gskit.h
+++ b/lib/vtls/gskit.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c
index 16b0bd6cb..e848c3f05 100644
--- a/lib/vtls/gtls.c
+++ b/lib/vtls/gtls.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -81,7 +81,7 @@ static bool gtls_inited = FALSE;
struct ssl_backend_data {
gnutls_session_t session;
gnutls_certificate_credentials_t cred;
-#ifdef USE_TLS_SRP
+#ifdef HAVE_GNUTLS_SRP
gnutls_srp_client_credentials_t srp_client_cred;
#endif
};
@@ -304,7 +304,7 @@ static gnutls_x509_crt_fmt_t do_file_type(const char *type)
return GNUTLS_X509_FMT_PEM;
if(strcasecompare(type, "DER"))
return GNUTLS_X509_FMT_DER;
- return -1;
+ return GNUTLS_X509_FMT_PEM; /* default to PEM */
}
#define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509"
@@ -399,15 +399,8 @@ gtls_connect_step1(struct connectdata *conn,
#endif
const char *prioritylist;
const char *err = NULL;
-#ifndef CURL_DISABLE_PROXY
- const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
- conn->host.name;
- long * const certverifyresult = SSL_IS_PROXY() ?
- &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
-#else
- const char * const hostname = conn->host.name;
- long * const certverifyresult = &data->set.ssl.certverifyresult;
-#endif
+ const char * const hostname = SSL_HOST_NAME();
+ long * const certverifyresult = &SSL_SET_OPTION_LVALUE(certverifyresult);
if(connssl->state == ssl_connection_complete)
/* to make us tolerant against being called more than once for the
@@ -434,7 +427,7 @@ gtls_connect_step1(struct connectdata *conn,
return CURLE_SSL_CONNECT_ERROR;
}
-#ifdef USE_TLS_SRP
+#ifdef HAVE_GNUTLS_SRP
if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) {
infof(data, "Using TLS-SRP username: %s\n", SSL_SET_OPTION(username));
@@ -588,7 +581,7 @@ gtls_connect_step1(struct connectdata *conn,
return CURLE_SSL_CONNECT_ERROR;
}
-#ifdef USE_TLS_SRP
+#ifdef HAVE_GNUTLS_SRP
/* Only add SRP to the cipher list if SRP is requested. Otherwise
* GnuTLS will disable TLS 1.3 support. */
if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) {
@@ -610,7 +603,7 @@ gtls_connect_step1(struct connectdata *conn,
else {
#endif
rc = gnutls_priority_set_direct(session, prioritylist, &err);
-#ifdef USE_TLS_SRP
+#ifdef HAVE_GNUTLS_SRP
}
#endif
@@ -645,7 +638,7 @@ gtls_connect_step1(struct connectdata *conn,
gnutls_alpn_set_protocols(session, protocols, cur, 0);
}
- if(SSL_SET_OPTION(cert)) {
+ if(SSL_SET_OPTION(primary.clientcert)) {
if(SSL_SET_OPTION(key_passwd)) {
const unsigned int supported_key_encryption_algorithms =
GNUTLS_PKCS_USE_PKCS12_3DES | GNUTLS_PKCS_USE_PKCS12_ARCFOUR |
@@ -654,9 +647,9 @@ gtls_connect_step1(struct connectdata *conn,
GNUTLS_PKCS_USE_PBES2_AES_256;
rc = gnutls_certificate_set_x509_key_file2(
backend->cred,
- SSL_SET_OPTION(cert),
+ SSL_SET_OPTION(primary.clientcert),
SSL_SET_OPTION(key) ?
- SSL_SET_OPTION(key) : SSL_SET_OPTION(cert),
+ SSL_SET_OPTION(key) : SSL_SET_OPTION(primary.clientcert),
do_file_type(SSL_SET_OPTION(cert_type)),
SSL_SET_OPTION(key_passwd),
supported_key_encryption_algorithms);
@@ -670,9 +663,9 @@ gtls_connect_step1(struct connectdata *conn,
else {
if(gnutls_certificate_set_x509_key_file(
backend->cred,
- SSL_SET_OPTION(cert),
+ SSL_SET_OPTION(primary.clientcert),
SSL_SET_OPTION(key) ?
- SSL_SET_OPTION(key) : SSL_SET_OPTION(cert),
+ SSL_SET_OPTION(key) : SSL_SET_OPTION(primary.clientcert),
do_file_type(SSL_SET_OPTION(cert_type)) ) !=
GNUTLS_E_SUCCESS) {
failf(data, "error reading X.509 key or certificate file");
@@ -681,7 +674,7 @@ gtls_connect_step1(struct connectdata *conn,
}
}
-#ifdef USE_TLS_SRP
+#ifdef HAVE_GNUTLS_SRP
/* put the credentials to the current session */
if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) {
rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
@@ -839,15 +832,8 @@ gtls_connect_step3(struct connectdata *conn,
unsigned int bits;
gnutls_protocol_t version = gnutls_protocol_get_version(session);
#endif
-#ifndef CURL_DISABLE_PROXY
- const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
- conn->host.name;
- long * const certverifyresult = SSL_IS_PROXY() ?
- &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
-#else
- const char * const hostname = conn->host.name;
- long * const certverifyresult = &data->set.ssl.certverifyresult;
-#endif
+ const char * const hostname = SSL_HOST_NAME();
+ long * const certverifyresult = &SSL_SET_OPTION_LVALUE(certverifyresult);
/* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */
ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session),
@@ -868,7 +854,7 @@ gtls_connect_step3(struct connectdata *conn,
if(SSL_CONN_CONFIG(verifypeer) ||
SSL_CONN_CONFIG(verifyhost) ||
SSL_SET_OPTION(issuercert)) {
-#ifdef USE_TLS_SRP
+#ifdef HAVE_GNUTLS_SRP
if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP
&& SSL_SET_OPTION(username) != NULL
&& !SSL_CONN_CONFIG(verifypeer)
@@ -881,7 +867,7 @@ gtls_connect_step3(struct connectdata *conn,
failf(data, "failed to get server cert");
*certverifyresult = GNUTLS_E_NO_CERTIFICATE_FOUND;
return CURLE_PEER_FAILED_VERIFICATION;
-#ifdef USE_TLS_SRP
+#ifdef HAVE_GNUTLS_SRP
}
#endif
}
@@ -1128,22 +1114,15 @@ gtls_connect_step3(struct connectdata *conn,
}
#endif
if(!rc) {
-#ifndef CURL_DISABLE_PROXY
- const char * const dispname = SSL_IS_PROXY() ?
- conn->http_proxy.host.dispname : conn->host.dispname;
-#else
- const char * const dispname = conn->host.dispname;
-#endif
-
if(SSL_CONN_CONFIG(verifyhost)) {
failf(data, "SSL: certificate subject name (%s) does not match "
- "target host name '%s'", certname, dispname);
+ "target host name '%s'", certname, SSL_HOST_DISPNAME());
gnutls_x509_crt_deinit(x509_cert);
return CURLE_PEER_FAILED_VERIFICATION;
}
else
infof(data, "\t common name: %s (does not match '%s')\n",
- certname, dispname);
+ certname, SSL_HOST_DISPNAME());
}
else
infof(data, "\t common name: %s (matched)\n", certname);
@@ -1246,13 +1225,18 @@ gtls_connect_step3(struct connectdata *conn,
certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
showtime(data, "expire date", certclock);
+
+ gnutls_free(certfields.data);
}
rc = gnutls_x509_crt_get_issuer_dn2(x509_cert, &certfields);
if(rc)
infof(data, "Failed to get certificate issuer\n");
- else
+ else {
infof(data, "\t issuer: %s\n", certfields.data);
+
+ gnutls_free(certfields.data);
+ }
#endif
gnutls_x509_crt_deinit(x509_cert);
@@ -1448,7 +1432,7 @@ static void close_one(struct ssl_connect_data *connssl)
gnutls_certificate_free_credentials(backend->cred);
backend->cred = NULL;
}
-#ifdef USE_TLS_SRP
+#ifdef HAVE_GNUTLS_SRP
if(backend->srp_client_cred) {
gnutls_srp_free_client_credentials(backend->srp_client_cred);
backend->srp_client_cred = NULL;
@@ -1530,7 +1514,7 @@ static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
}
gnutls_certificate_free_credentials(backend->cred);
-#ifdef USE_TLS_SRP
+#ifdef HAVE_GNUTLS_SRP
if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP
&& SSL_SET_OPTION(username) != NULL)
gnutls_srp_free_client_credentials(backend->srp_client_cred);
diff --git a/lib/vtls/gtls.h b/lib/vtls/gtls.h
index 780fc109d..1a146a3a9 100644
--- a/lib/vtls/gtls.h
+++ b/lib/vtls/gtls.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/keylog.c b/lib/vtls/keylog.c
index 70d22ecf0..a45945f8f 100644
--- a/lib/vtls/keylog.c
+++ b/lib/vtls/keylog.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/keylog.h b/lib/vtls/keylog.h
index c6b99db93..63626da90 100644
--- a/lib/vtls/keylog.h
+++ b/lib/vtls/keylog.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c
index 545f824c6..191315df8 100644
--- a/lib/vtls/mbedtls.c
+++ b/lib/vtls/mbedtls.c
@@ -10,7 +10,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -31,6 +31,9 @@
#ifdef USE_MBEDTLS
+/* Define this to enable lots of debugging for mbedTLS */
+/* #define MBEDTLS_DEBUG */
+
#include <mbedtls/version.h>
#if MBEDTLS_VERSION_NUMBER >= 0x02040000
#include <mbedtls/net_sockets.h>
@@ -46,6 +49,12 @@
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/sha256.h>
+#if MBEDTLS_VERSION_MAJOR >= 2
+# ifdef MBEDTLS_DEBUG
+# include <mbedtls/debug.h>
+# endif
+#endif
+
#include "urldata.h"
#include "sendf.h"
#include "inet_pton.h"
@@ -113,9 +122,6 @@ static int entropy_func_mutex(void *data, unsigned char *output, size_t len)
#endif /* THREADING_SUPPORT */
-/* Define this to enable lots of debugging for mbedTLS */
-#undef MBEDTLS_DEBUG
-
#ifdef MBEDTLS_DEBUG
static void mbed_debug(void *context, int level, const char *f_name,
int line_nb, const char *line)
@@ -244,7 +250,7 @@ mbed_connect_step1(struct connectdata *conn,
const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
- char * const ssl_cert = SSL_SET_OPTION(cert);
+ char * const ssl_cert = SSL_SET_OPTION(primary.clientcert);
const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile);
#ifndef CURL_DISABLE_PROXY
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
diff --git a/lib/vtls/mbedtls.h b/lib/vtls/mbedtls.h
index 0cc64b399..1abd331ea 100644
--- a/lib/vtls/mbedtls.h
+++ b/lib/vtls/mbedtls.h
@@ -7,12 +7,12 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/mbedtls_threadlock.c b/lib/vtls/mbedtls_threadlock.c
index 4d672f106..473f5171e 100644
--- a/lib/vtls/mbedtls_threadlock.c
+++ b/lib/vtls/mbedtls_threadlock.c
@@ -10,7 +10,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/mbedtls_threadlock.h b/lib/vtls/mbedtls_threadlock.h
index 96a787d1a..e40dfc8d6 100644
--- a/lib/vtls/mbedtls_threadlock.h
+++ b/lib/vtls/mbedtls_threadlock.h
@@ -12,7 +12,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/mesalink.c b/lib/vtls/mesalink.c
index 7132bdfd2..309786cf8 100644
--- a/lib/vtls/mesalink.c
+++ b/lib/vtls/mesalink.c
@@ -10,7 +10,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -158,8 +158,8 @@ mesalink_connect_step1(struct connectdata *conn, int sockindex)
SSL_CONN_CONFIG(CApath))) {
if(SSL_CONN_CONFIG(verifypeer)) {
failf(data,
- "error setting certificate verify locations:\n"
- " CAfile: %s\n CApath: %s",
+ "error setting certificate verify locations: "
+ " CAfile: %s CApath: %s",
SSL_CONN_CONFIG(CAfile) ?
SSL_CONN_CONFIG(CAfile) : "none",
SSL_CONN_CONFIG(CApath) ?
@@ -173,20 +173,18 @@ mesalink_connect_step1(struct connectdata *conn, int sockindex)
else {
infof(data, "successfully set certificate verify locations:\n");
}
- infof(data,
- " CAfile: %s\n"
- " CApath: %s\n",
- SSL_CONN_CONFIG(CAfile)?
- SSL_CONN_CONFIG(CAfile): "none",
- SSL_CONN_CONFIG(CApath)?
- SSL_CONN_CONFIG(CApath): "none");
+ infof(data, " CAfile: %s\n",
+ SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile): "none");
+ infof(data, " CApath: %s\n",
+ SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath): "none");
}
- if(SSL_SET_OPTION(cert) && SSL_SET_OPTION(key)) {
+ if(SSL_SET_OPTION(primary.clientcert) && SSL_SET_OPTION(key)) {
int file_type = do_file_type(SSL_SET_OPTION(cert_type));
- if(SSL_CTX_use_certificate_chain_file(BACKEND->ctx, SSL_SET_OPTION(cert),
- file_type) != 1) {
+ if(SSL_CTX_use_certificate_chain_file(BACKEND->ctx,
+ SSL_SET_OPTION(primary.clientcert),
+ file_type) != 1) {
failf(data, "unable to use client certificate (no key or wrong pass"
" phrase?)");
return CURLE_SSL_CONNECT_ERROR;
diff --git a/lib/vtls/mesalink.h b/lib/vtls/mesalink.h
index 54cb94ad3..03f520c1d 100644
--- a/lib/vtls/mesalink.h
+++ b/lib/vtls/mesalink.h
@@ -7,12 +7,12 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2017-2018, Yiming Jing, <jingyiming@baidu.com>
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2017 - 2018, Yiming Jing, <jingyiming@baidu.com>
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c
index 0f0d1ee6c..59649ccc3 100644
--- a/lib/vtls/nss.c
+++ b/lib/vtls/nss.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -83,7 +83,7 @@ struct ssl_backend_data {
PRFileDesc *handle;
char *client_nickname;
struct Curl_easy *data;
- struct curl_llist obj_list;
+ struct Curl_llist obj_list;
PK11GenericObject *obj_clicert;
};
@@ -91,14 +91,14 @@ static PRLock *nss_initlock = NULL;
static PRLock *nss_crllock = NULL;
static PRLock *nss_findslot_lock = NULL;
static PRLock *nss_trustload_lock = NULL;
-static struct curl_llist nss_crl_list;
+static struct Curl_llist nss_crl_list;
static NSSInitContext *nss_context = NULL;
static volatile int initialized = 0;
/* type used to wrap pointers as list nodes */
struct ptr_list_wrap {
void *ptr;
- struct curl_llist_element node;
+ struct Curl_llist_element node;
};
struct cipher_s {
@@ -430,7 +430,7 @@ static PK11SlotInfo* nss_find_slot_by_name(const char *slot_name)
}
/* wrap 'ptr' as list node and tail-insert into 'list' */
-static CURLcode insert_wrapped_ptr(struct curl_llist *list, void *ptr)
+static CURLcode insert_wrapped_ptr(struct Curl_llist *list, void *ptr)
{
struct ptr_list_wrap *wrap = malloc(sizeof(*wrap));
if(!wrap)
@@ -1027,12 +1027,7 @@ static SECStatus BadCertHandler(void *arg, PRFileDesc *sock)
CERTCertificate *cert;
/* remember the cert verification result */
-#ifndef CURL_DISABLE_PROXY
- if(SSL_IS_PROXY())
- data->set.proxy_ssl.certverifyresult = err;
- else
-#endif
- data->set.ssl.certverifyresult = err;
+ SSL_SET_OPTION_LVALUE(certverifyresult) = err;
if(err == SSL_ERROR_BAD_CERT_DOMAIN && !SSL_CONN_CONFIG(verifyhost))
/* we are asked not to verify the host name */
@@ -1631,9 +1626,8 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn,
if(capath && !capath[0])
capath = NULL;
- infof(data, " CAfile: %s\n CApath: %s\n",
- cafile ? cafile : "none",
- capath ? capath : "none");
+ infof(data, " CAfile: %s\n", cafile ? cafile : "none");
+ infof(data, " CApath: %s\n", capath ? capath : "none");
/* load libnssckbi.so if no other trust roots were specified */
use_trust_module = !cafile && !capath;
@@ -1673,7 +1667,8 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn,
if(!dir)
return CURLE_SSL_CACERT_BADFILE;
- while((entry = PR_ReadDir(dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN))) {
+ while((entry =
+ PR_ReadDir(dir, (PRDirFlags)(PR_SKIP_BOTH | PR_SKIP_HIDDEN)))) {
char *fullpath = aprintf("%s/%s", capath, entry->name);
if(!fullpath) {
PR_CloseDir(dir);
@@ -1838,12 +1833,6 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
CURLcode result;
bool second_layer = FALSE;
SSLVersionRange sslver_supported;
-#ifndef CURL_DISABLE_PROXY
- const char *hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
- conn->host.name;
-#else
- const char *hostname = conn->host.name;
-#endif
SSLVersionRange sslver = {
SSL_LIBRARY_VERSION_TLS_1_0, /* min */
@@ -1948,12 +1937,7 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
goto error;
/* not checked yet */
-#ifndef CURL_DISABLE_PROXY
- if(SSL_IS_PROXY())
- data->set.proxy_ssl.certverifyresult = 0;
- else
-#endif
- data->set.ssl.certverifyresult = 0;
+ SSL_SET_OPTION_LVALUE(certverifyresult) = 0;
if(SSL_BadCertHook(model, BadCertHandler, conn) != SECSuccess)
goto error;
@@ -1981,14 +1965,15 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
infof(data, " CRLfile: %s\n", SSL_SET_OPTION(CRLfile));
}
- if(SSL_SET_OPTION(cert)) {
- char *nickname = dup_nickname(data, SSL_SET_OPTION(cert));
+ if(SSL_SET_OPTION(primary.clientcert)) {
+ char *nickname = dup_nickname(data, SSL_SET_OPTION(primary.clientcert));
if(nickname) {
/* we are not going to use libnsspem.so to read the client cert */
backend->obj_clicert = NULL;
}
else {
- CURLcode rv = cert_stuff(conn, sockindex, SSL_SET_OPTION(cert),
+ CURLcode rv = cert_stuff(conn, sockindex,
+ SSL_SET_OPTION(primary.clientcert),
SSL_SET_OPTION(key));
if(rv) {
/* failf() is already done in cert_stuff() */
@@ -2124,11 +2109,11 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
goto error;
/* propagate hostname to the TLS layer */
- if(SSL_SetURL(backend->handle, hostname) != SECSuccess)
+ if(SSL_SetURL(backend->handle, SSL_HOST_NAME()) != SECSuccess)
goto error;
/* prevent NSS from re-using the session for a different hostname */
- if(SSL_SetSockPeerID(backend->handle, hostname) != SECSuccess)
+ if(SSL_SetSockPeerID(backend->handle, SSL_HOST_NAME()) != SECSuccess)
goto error;
return CURLE_OK;
@@ -2147,18 +2132,6 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
struct Curl_easy *data = conn->data;
CURLcode result = CURLE_SSL_CONNECT_ERROR;
PRUint32 timeout;
-#ifndef CURL_DISABLE_PROXY
- long * const certverifyresult = SSL_IS_PROXY() ?
- &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
- const char * const pinnedpubkey = SSL_IS_PROXY() ?
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
-#else
- long * const certverifyresult = &data->set.ssl.certverifyresult;
- const char * const pinnedpubkey =
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
-#endif
-
/* check timeout situation */
const timediff_t time_left = Curl_timeleft(data, NULL, TRUE);
@@ -2174,9 +2147,9 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
if(PR_GetError() == PR_WOULD_BLOCK_ERROR)
/* blocking direction is updated by nss_update_connecting_state() */
return CURLE_AGAIN;
- else if(*certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
+ else if(SSL_SET_OPTION(certverifyresult) == SSL_ERROR_BAD_CERT_DOMAIN)
result = CURLE_PEER_FAILED_VERIFICATION;
- else if(*certverifyresult != 0)
+ else if(SSL_SET_OPTION(certverifyresult) != 0)
result = CURLE_PEER_FAILED_VERIFICATION;
goto error;
}
@@ -2204,7 +2177,7 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
}
}
- result = cmp_peer_pubkey(connssl, pinnedpubkey);
+ result = cmp_peer_pubkey(connssl, SSL_PINNED_PUB_KEY());
if(result)
/* status already printed */
goto error;
diff --git a/lib/vtls/nssg.h b/lib/vtls/nssg.h
index 41e51b021..37b364647 100644
--- a/lib/vtls/nssg.h
+++ b/lib/vtls/nssg.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index 1685a4aa4..e9c535f8f 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -34,6 +34,13 @@
/* Wincrypt must be included before anything that could include OpenSSL. */
#if defined(USE_WIN32_CRYPTO)
#include <wincrypt.h>
+/* Undefine wincrypt conflicting symbols for BoringSSL. */
+#undef X509_NAME
+#undef X509_EXTENSIONS
+#undef PKCS7_ISSUER_AND_SERIAL
+#undef PKCS7_SIGNER_INFO
+#undef OCSP_REQUEST
+#undef OCSP_RESPONSE
#endif
#include "urldata.h"
@@ -193,6 +200,10 @@
!defined(OPENSSL_IS_BORINGSSL))
#define HAVE_SSL_CTX_SET_CIPHERSUITES
#define HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
+/* SET_EC_CURVES available under the same preconditions: see
+ * https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_groups.html
+ */
+#define HAVE_SSL_CTX_SET_EC_CURVES
#endif
#if defined(LIBRESSL_VERSION_NUMBER)
@@ -214,6 +225,14 @@
"ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH"
#endif
+#ifdef HAVE_OPENSSL_SRP
+/* the function exists */
+#ifdef USE_TLS_SRP
+/* the functionality is not disabled */
+#define USE_OPENSSL_SRP
+#endif
+#endif
+
struct ssl_backend_data {
/* these ones requires specific SSL-types */
SSL_CTX* ctx;
@@ -1065,9 +1084,6 @@ int cert_stuff(struct connectdata *conn,
/* returns non-zero on failure */
static int x509_name_oneline(X509_NAME *a, char *buf, size_t size)
{
-#if 0
- return X509_NAME_oneline(a, buf, size);
-#else
BIO *bio_out = BIO_new(BIO_s_mem());
BUF_MEM *biomem;
int rc;
@@ -1089,7 +1105,6 @@ static int x509_name_oneline(X509_NAME *a, char *buf, size_t size)
BIO_free(bio_out);
return !rc;
-#endif
}
/**
@@ -1100,6 +1115,21 @@ static int x509_name_oneline(X509_NAME *a, char *buf, size_t size)
*/
static int Curl_ossl_init(void)
{
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \
+ !defined(LIBRESSL_VERSION_NUMBER)
+ const uint64_t flags =
+#ifdef OPENSSL_INIT_ENGINE_ALL_BUILTIN
+ /* not present in BoringSSL */
+ OPENSSL_INIT_ENGINE_ALL_BUILTIN |
+#endif
+#ifdef CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG
+ OPENSSL_INIT_NO_LOAD_CONFIG |
+#else
+ OPENSSL_INIT_LOAD_CONFIG |
+#endif
+ 0;
+ OPENSSL_init_ssl(flags, NULL);
+#else
OPENSSL_load_builtin_modules();
#ifdef USE_OPENSSL_ENGINE
@@ -1118,10 +1148,6 @@ static int Curl_ossl_init(void)
CONF_MFLAGS_IGNORE_MISSING_FILE);
#endif
-#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \
- !defined(LIBRESSL_VERSION_NUMBER)
- /* OpenSSL 1.1.0+ takes care of initialization itself */
-#else
/* Lets get nice error messages */
SSL_load_error_strings();
@@ -1571,16 +1597,8 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert)
CURLcode result = CURLE_OK;
bool dNSName = FALSE; /* if a dNSName field exists in the cert */
bool iPAddress = FALSE; /* if a iPAddress field exists in the cert */
-#ifndef CURL_DISABLE_PROXY
- const char * const hostname = SSL_IS_PROXY() ?
- conn->http_proxy.host.name : conn->host.name;
- const char * const dispname = SSL_IS_PROXY() ?
- conn->http_proxy.host.dispname : conn->host.dispname;
-#else
- /* disabled proxy support */
- const char * const hostname = conn->host.name;
- const char * const dispname = conn->host.dispname;
-#endif
+ const char * const hostname = SSL_HOST_NAME();
+ const char * const dispname = SSL_HOST_DISPNAME();
#ifdef ENABLE_IPV6
if(conn->bits.ipv6_ip &&
@@ -1777,6 +1795,11 @@ static CURLcode verifystatus(struct connectdata *conn,
X509_STORE *st = NULL;
STACK_OF(X509) *ch = NULL;
struct ssl_backend_data *backend = connssl->backend;
+ X509 *cert;
+ OCSP_CERTID *id = NULL;
+ int cert_status, crl_reason;
+ ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
+ int ret;
long len = SSL_get_tlsext_status_ocsp_resp(backend->handle, &status);
@@ -1845,43 +1868,63 @@ static CURLcode verifystatus(struct connectdata *conn,
goto end;
}
- for(i = 0; i < OCSP_resp_count(br); i++) {
- int cert_status, crl_reason;
- OCSP_SINGLERESP *single = NULL;
-
- ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
+ /* Compute the certificate's ID */
+ cert = SSL_get_peer_certificate(backend->handle);
+ if(!cert) {
+ failf(data, "Error getting peer certficate");
+ result = CURLE_SSL_INVALIDCERTSTATUS;
+ goto end;
+ }
- single = OCSP_resp_get0(br, i);
- if(!single)
- continue;
+ for(i = 0; i < sk_X509_num(ch); i++) {
+ X509 *issuer = sk_X509_value(ch, i);
+ if(X509_check_issued(issuer, cert) == X509_V_OK) {
+ id = OCSP_cert_to_id(EVP_sha1(), cert, issuer);
+ break;
+ }
+ }
+ X509_free(cert);
- cert_status = OCSP_single_get0_status(single, &crl_reason, &rev,
- &thisupd, &nextupd);
+ if(!id) {
+ failf(data, "Error computing OCSP ID");
+ result = CURLE_SSL_INVALIDCERTSTATUS;
+ goto end;
+ }
- if(!OCSP_check_validity(thisupd, nextupd, 300L, -1L)) {
- failf(data, "OCSP response has expired");
- result = CURLE_SSL_INVALIDCERTSTATUS;
- goto end;
- }
+ /* Find the single OCSP response corresponding to the certificate ID */
+ ret = OCSP_resp_find_status(br, id, &cert_status, &crl_reason, &rev,
+ &thisupd, &nextupd);
+ OCSP_CERTID_free(id);
+ if(ret != 1) {
+ failf(data, "Could not find certificate ID in OCSP response");
+ result = CURLE_SSL_INVALIDCERTSTATUS;
+ goto end;
+ }
- infof(data, "SSL certificate status: %s (%d)\n",
- OCSP_cert_status_str(cert_status), cert_status);
+ /* Validate the corresponding single OCSP response */
+ if(!OCSP_check_validity(thisupd, nextupd, 300L, -1L)) {
+ failf(data, "OCSP response has expired");
+ result = CURLE_SSL_INVALIDCERTSTATUS;
+ goto end;
+ }
- switch(cert_status) {
- case V_OCSP_CERTSTATUS_GOOD:
- break;
+ infof(data, "SSL certificate status: %s (%d)\n",
+ OCSP_cert_status_str(cert_status), cert_status);
- case V_OCSP_CERTSTATUS_REVOKED:
- result = CURLE_SSL_INVALIDCERTSTATUS;
+ switch(cert_status) {
+ case V_OCSP_CERTSTATUS_GOOD:
+ break;
- failf(data, "SSL certificate revocation reason: %s (%d)",
- OCSP_crl_reason_str(crl_reason), crl_reason);
- goto end;
+ case V_OCSP_CERTSTATUS_REVOKED:
+ result = CURLE_SSL_INVALIDCERTSTATUS;
+ failf(data, "SSL certificate revocation reason: %s (%d)",
+ OCSP_crl_reason_str(crl_reason), crl_reason);
+ goto end;
- case V_OCSP_CERTSTATUS_UNKNOWN:
- result = CURLE_SSL_INVALIDCERTSTATUS;
- goto end;
- }
+ case V_OCSP_CERTSTATUS_UNKNOWN:
+ default:
+ result = CURLE_SSL_INVALIDCERTSTATUS;
+ goto end;
}
end:
@@ -2459,12 +2502,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
bool sni;
-#ifndef CURL_DISABLE_PROXY
- const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
- conn->host.name;
-#else
- const char * const hostname = conn->host.name;
-#endif
+ const char * const hostname = SSL_HOST_NAME();
#ifdef ENABLE_IPV6
struct in6_addr addr;
@@ -2472,18 +2510,12 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
struct in_addr addr;
#endif
#endif
-#ifndef CURL_DISABLE_PROXY
- long * const certverifyresult = SSL_IS_PROXY() ?
- &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
-#else
- long * const certverifyresult = &data->set.ssl.certverifyresult;
-#endif
const long int ssl_version = SSL_CONN_CONFIG(version);
-#ifdef USE_TLS_SRP
+#ifdef USE_OPENSSL_SRP
const enum CURL_TLSAUTH ssl_authtype = SSL_SET_OPTION(authtype);
#endif
- char * const ssl_cert = SSL_SET_OPTION(cert);
- const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(cert_blob);
+ char * const ssl_cert = SSL_SET_OPTION(primary.clientcert);
+ const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob);
const char * const ssl_cert_type = SSL_SET_OPTION(cert_type);
const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
@@ -2500,7 +2532,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
if(result)
return result;
- *certverifyresult = !X509_V_OK;
+ SSL_SET_OPTION_LVALUE(certverifyresult) = !X509_V_OK;
/* check to see if we've been told to use an explicit SSL/TLS version */
@@ -2524,7 +2556,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
failf(data, OSSL_PACKAGE " was built without SSLv2 support");
return CURLE_NOT_BUILT_IN;
#else
-#ifdef USE_TLS_SRP
+#ifdef USE_OPENSSL_SRP
if(ssl_authtype == CURL_TLSAUTH_SRP)
return CURLE_SSL_CONNECT_ERROR;
#endif
@@ -2537,7 +2569,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
failf(data, OSSL_PACKAGE " was built without SSLv3 support");
return CURLE_NOT_BUILT_IN;
#else
-#ifdef USE_TLS_SRP
+#ifdef USE_OPENSSL_SRP
if(ssl_authtype == CURL_TLSAUTH_SRP)
return CURLE_SSL_CONNECT_ERROR;
#endif
@@ -2735,33 +2767,33 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
if(ssl_cert || ssl_cert_blob || ssl_cert_type) {
BIO *ssl_cert_bio = NULL;
BIO *ssl_key_bio = NULL;
- int result_cert_stuff;
if(ssl_cert_blob) {
/* the typecast of blob->len is fine since it is guaranteed to never be
larger than CURL_MAX_INPUT_LENGTH */
ssl_cert_bio = BIO_new_mem_buf(ssl_cert_blob->data,
(int)ssl_cert_blob->len);
if(!ssl_cert_bio)
- return CURLE_SSL_CERTPROBLEM;
+ result = CURLE_OUT_OF_MEMORY;
}
- if(SSL_SET_OPTION(key_blob)) {
+ if(!result && SSL_SET_OPTION(key_blob)) {
ssl_key_bio = BIO_new_mem_buf(SSL_SET_OPTION(key_blob)->data,
(int)SSL_SET_OPTION(key_blob)->len);
if(!ssl_key_bio)
- return CURLE_SSL_CERTPROBLEM;
+ result = CURLE_OUT_OF_MEMORY;
}
- result_cert_stuff = cert_stuff(conn, backend->ctx,
+ if(!result &&
+ !cert_stuff(conn, backend->ctx,
ssl_cert, ssl_cert_bio, ssl_cert_type,
SSL_SET_OPTION(key), ssl_key_bio,
- SSL_SET_OPTION(key_type), SSL_SET_OPTION(key_passwd));
+ SSL_SET_OPTION(key_type), SSL_SET_OPTION(key_passwd)))
+ result = CURLE_SSL_CERTPROBLEM;
if(ssl_cert_bio)
BIO_free(ssl_cert_bio);
if(ssl_key_bio)
BIO_free(ssl_key_bio);
- if(!result_cert_stuff) {
+ if(result)
/* failf() is already done in cert_stuff() */
- return CURLE_SSL_CERTPROBLEM;
- }
+ return result;
}
ciphers = SSL_CONN_CONFIG(cipher_list);
@@ -2793,7 +2825,19 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
SSL_CTX_set_post_handshake_auth(backend->ctx, 1);
#endif
-#ifdef USE_TLS_SRP
+#ifdef HAVE_SSL_CTX_SET_EC_CURVES
+ {
+ char *curves = SSL_CONN_CONFIG(curves);
+ if(curves) {
+ if(!SSL_CTX_set1_curves_list(backend->ctx, curves)) {
+ failf(data, "failed setting curves list: '%s'", curves);
+ return CURLE_SSL_CIPHER;
+ }
+ }
+ }
+#endif
+
+#ifdef USE_OPENSSL_SRP
if(ssl_authtype == CURL_TLSAUTH_SRP) {
char * const ssl_username = SSL_SET_OPTION(username);
@@ -2910,7 +2954,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
/* "If GetLastError returns CRYPT_E_NOT_FOUND, the certificate is
good for all uses. If it returns zero, the certificate has no
valid uses." */
- if(GetLastError() != CRYPT_E_NOT_FOUND)
+ if((HRESULT)GetLastError() != CRYPT_E_NOT_FOUND)
continue;
}
else {
@@ -2970,7 +3014,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
{
if(ssl_cafile) {
if(!SSL_CTX_load_verify_file(backend->ctx, ssl_cafile)) {
- if(verifypeer) {
+ if(verifypeer && !imported_native_ca) {
/* Fail if we insist on successfully verifying the server. */
failf(data, "error setting certificate file: %s", ssl_cafile);
return CURLE_SSL_CACERT_BADFILE;
@@ -2978,11 +3022,11 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
/* Continue with a warning if no certificate verif is required. */
infof(data, "error setting certificate file, continuing anyway\n");
}
- infof(data, " CAfile: %s\n", ssl_cafile);
+ infof(data, " CAfile: %s\n", ssl_cafile);
}
if(ssl_capath) {
if(!SSL_CTX_load_verify_dir(backend->ctx, ssl_capath)) {
- if(verifypeer) {
+ if(verifypeer && !imported_native_ca) {
/* Fail if we insist on successfully verifying the server. */
failf(data, "error setting certificate path: %s", ssl_capath);
return CURLE_SSL_CACERT_BADFILE;
@@ -2990,7 +3034,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
/* Continue with a warning if no certificate verif is required. */
infof(data, "error setting certificate path, continuing anyway\n");
}
- infof(data, " CApath: %s\n", ssl_capath);
+ infof(data, " CApath: %s\n", ssl_capath);
}
}
#else
@@ -3000,8 +3044,8 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
if(!SSL_CTX_load_verify_locations(backend->ctx, ssl_cafile, ssl_capath)) {
if(verifypeer && !imported_native_ca) {
/* Fail if we insist on successfully verifying the server. */
- failf(data, "error setting certificate verify locations:\n"
- " CAfile: %s\n CApath: %s",
+ failf(data, "error setting certificate verify locations:"
+ " CAfile: %s CApath: %s",
ssl_cafile ? ssl_cafile : "none",
ssl_capath ? ssl_capath : "none");
return CURLE_SSL_CACERT_BADFILE;
@@ -3015,11 +3059,8 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
/* Everything is fine. */
infof(data, "successfully set certificate verify locations:\n");
}
- infof(data,
- " CAfile: %s\n"
- " CApath: %s\n",
- ssl_cafile ? ssl_cafile : "none",
- ssl_capath ? ssl_capath : "none");
+ infof(data, " CAfile: %s\n", ssl_cafile ? ssl_cafile : "none");
+ infof(data, " CApath: %s\n", ssl_capath ? ssl_capath : "none");
}
#endif
@@ -3201,12 +3242,6 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
struct Curl_easy *data = conn->data;
int err;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-#ifndef CURL_DISABLE_PROXY
- long * const certverifyresult = SSL_IS_PROXY() ?
- &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
-#else
- long * const certverifyresult = &data->set.ssl.certverifyresult;
-#endif
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
|| ssl_connect_2_reading == connssl->connecting_state
@@ -3265,12 +3300,13 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
reason = ERR_GET_REASON(errdetail);
if((lib == ERR_LIB_SSL) &&
- (reason == SSL_R_CERTIFICATE_VERIFY_FAILED)) {
+ ((reason == SSL_R_CERTIFICATE_VERIFY_FAILED) ||
+ (reason == SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED))) {
result = CURLE_PEER_FAILED_VERIFICATION;
lerr = SSL_get_verify_result(backend->handle);
if(lerr != X509_V_OK) {
- *certverifyresult = lerr;
+ SSL_SET_OPTION_LVALUE(certverifyresult) = lerr;
msnprintf(error_buffer, sizeof(error_buffer),
"SSL certificate problem: %s",
X509_verify_cert_error_string(lerr));
@@ -3292,12 +3328,10 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
* the SO_ERROR is also lost.
*/
if(CURLE_SSL_CONNECT_ERROR == result && errdetail == 0) {
+ const char * const hostname = SSL_HOST_NAME();
#ifndef CURL_DISABLE_PROXY
- const char * const hostname = SSL_IS_PROXY() ?
- conn->http_proxy.host.name : conn->host.name;
const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
#else
- const char * const hostname = conn->host.name;
const long int port = conn->remote_port;
#endif
char extramsg[80]="";
@@ -3459,7 +3493,6 @@ typedef int numcert_t;
static CURLcode get_cert_chain(struct connectdata *conn,
struct ssl_connect_data *connssl)
-
{
CURLcode result;
STACK_OF(X509) *sk;
@@ -3752,12 +3785,6 @@ static CURLcode servercert(struct connectdata *conn,
char error_buffer[256]="";
char buffer[2048];
const char *ptr;
-#ifndef CURL_DISABLE_PROXY
- long * const certverifyresult = SSL_IS_PROXY() ?
- &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
-#else
- long * const certverifyresult = &data->set.ssl.certverifyresult;
-#endif
BIO *mem = BIO_new(BIO_s_mem());
struct ssl_backend_data *backend = connssl->backend;
@@ -3878,9 +3905,9 @@ static CURLcode servercert(struct connectdata *conn,
X509_free(issuer);
}
- lerr = *certverifyresult = SSL_get_verify_result(backend->handle);
-
- if(*certverifyresult != X509_V_OK) {
+ lerr = SSL_get_verify_result(backend->handle);
+ SSL_SET_OPTION_LVALUE(certverifyresult) = lerr;
+ if(lerr != X509_V_OK) {
if(SSL_CONN_CONFIG(verifypeer)) {
/* We probably never reach this, because SSL_connect() will fail
and we return earlier if verifypeer is set? */
@@ -4369,7 +4396,9 @@ static CURLcode Curl_ossl_md5sum(unsigned char *tmp, /* input */
(void) unused;
mdctx = EVP_MD_CTX_create();
- EVP_DigestInit_ex(mdctx, EVP_md5(), NULL);
+ if(!mdctx)
+ return CURLE_OUT_OF_MEMORY;
+ EVP_DigestInit(mdctx, EVP_md5());
EVP_DigestUpdate(mdctx, tmp, tmplen);
EVP_DigestFinal_ex(mdctx, md5sum, &len);
EVP_MD_CTX_destroy(mdctx);
@@ -4387,7 +4416,9 @@ static CURLcode Curl_ossl_sha256sum(const unsigned char *tmp, /* input */
(void) unused;
mdctx = EVP_MD_CTX_create();
- EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL);
+ if(!mdctx)
+ return CURLE_OUT_OF_MEMORY;
+ EVP_DigestInit(mdctx, EVP_sha256());
EVP_DigestUpdate(mdctx, tmp, tmplen);
EVP_DigestFinal_ex(mdctx, sha256sum, &len);
EVP_MD_CTX_destroy(mdctx);
diff --git a/lib/vtls/openssl.h b/lib/vtls/openssl.h
index 114dc4bae..2f6e1b2db 100644
--- a/lib/vtls/openssl.h
+++ b/lib/vtls/openssl.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c
index 1c1432d75..d7bc38917 100644
--- a/lib/vtls/schannel.c
+++ b/lib/vtls/schannel.c
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -346,6 +346,8 @@ set_ssl_ciphers(SCHANNEL_CRED *schannel_cred, char *ciphers)
}
#ifdef HAS_CLIENT_CERT_PATH
+
+/* Function allocates memory for store_path only if CURLE_OK is returned */
static CURLcode
get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path,
TCHAR **thumbprint)
@@ -388,16 +390,16 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path,
if(sep == NULL)
return CURLE_SSL_CERTPROBLEM;
+ *thumbprint = sep + 1;
+ if(_tcslen(*thumbprint) != CERT_THUMBPRINT_STR_LEN)
+ return CURLE_SSL_CERTPROBLEM;
+
*sep = TEXT('\0');
*store_path = _tcsdup(store_path_start);
*sep = TEXT('\\');
if(*store_path == NULL)
return CURLE_OUT_OF_MEMORY;
- *thumbprint = sep + 1;
- if(_tcslen(*thumbprint) != CERT_THUMBPRINT_STR_LEN)
- return CURLE_SSL_CERTPROBLEM;
-
return CURLE_OK;
}
#endif
@@ -418,7 +420,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
SCHANNEL_CRED schannel_cred;
PCCERT_CONTEXT client_certs[1] = { NULL };
SECURITY_STATUS sspi_status = SEC_E_OK;
- struct curl_schannel_cred *old_cred = NULL;
+ struct Curl_schannel_cred *old_cred = NULL;
struct in_addr addr;
#ifdef ENABLE_IPV6
struct in6_addr addr6;
@@ -588,7 +590,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
#ifdef HAS_CLIENT_CERT_PATH
/* client certificate */
- if(data->set.ssl.cert || data->set.ssl.cert_blob) {
+ if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) {
DWORD cert_store_name = 0;
TCHAR *cert_store_path = NULL;
TCHAR *cert_thumbprint_str = NULL;
@@ -598,27 +600,28 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
FILE *fInCert = NULL;
void *certdata = NULL;
size_t certsize = 0;
- bool blob = data->set.ssl.cert_blob != NULL;
+ bool blob = data->set.ssl.primary.cert_blob != NULL;
TCHAR *cert_path = NULL;
if(blob) {
- certdata = data->set.ssl.cert_blob->data;
- certsize = data->set.ssl.cert_blob->len;
+ certdata = data->set.ssl.primary.cert_blob->data;
+ certsize = data->set.ssl.primary.cert_blob->len;
}
else {
- cert_path = curlx_convert_UTF8_to_tchar(data->set.ssl.cert);
+ cert_path = curlx_convert_UTF8_to_tchar(
+ data->set.ssl.primary.clientcert);
if(!cert_path)
return CURLE_OUT_OF_MEMORY;
result = get_cert_location(cert_path, &cert_store_name,
&cert_store_path, &cert_thumbprint_str);
- if(result && (data->set.ssl.cert[0]!='\0'))
- fInCert = fopen(data->set.ssl.cert, "rb");
+ if(result && (data->set.ssl.primary.clientcert[0]!='\0'))
+ fInCert = fopen(data->set.ssl.primary.clientcert, "rb");
if(result && !fInCert) {
failf(data, "schannel: Failed to get certificate location"
" or file for %s",
- data->set.ssl.cert);
+ data->set.ssl.primary.clientcert);
curlx_unicodefree(cert_path);
return result;
}
@@ -628,7 +631,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
(!strcasecompare(data->set.ssl.cert_type, "P12"))) {
failf(data, "schannel: certificate format compatibility error "
" for %s",
- blob ? "(memory blob)" : data->set.ssl.cert);
+ blob ? "(memory blob)" : data->set.ssl.primary.clientcert);
curlx_unicodefree(cert_path);
return CURLE_SSL_CERTPROBLEM;
}
@@ -643,7 +646,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
size_t pwd_len = 0;
int str_w_len = 0;
const char *cert_showfilename_error = blob ?
- "(memory blob)" : data->set.ssl.cert;
+ "(memory blob)" : data->set.ssl.primary.clientcert;
curlx_unicodefree(cert_path);
if(fInCert) {
long cert_tell = 0;
@@ -664,7 +667,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
fclose(fInCert);
if(!continue_reading) {
failf(data, "schannel: Failed to read cert file %s",
- data->set.ssl.cert);
+ data->set.ssl.primary.clientcert);
free(certdata);
return CURLE_SSL_CERTPROBLEM;
}
@@ -771,15 +774,15 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
CertCloseStore(cert_store, 0);
}
#else
- if(data->set.ssl.cert) {
+ if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) {
failf(data, "schannel: client cert support not built in");
return CURLE_NOT_BUILT_IN;
}
#endif
/* allocate memory for the re-usable credential handle */
- BACKEND->cred = (struct curl_schannel_cred *)
- calloc(1, sizeof(struct curl_schannel_cred));
+ BACKEND->cred = (struct Curl_schannel_cred *)
+ calloc(1, sizeof(struct Curl_schannel_cred));
if(!BACKEND->cred) {
failf(data, "schannel: unable to allocate memory");
@@ -893,8 +896,8 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
ISC_REQ_STREAM;
/* allocate memory for the security context handle */
- BACKEND->ctxt = (struct curl_schannel_ctxt *)
- calloc(1, sizeof(struct curl_schannel_ctxt));
+ BACKEND->ctxt = (struct Curl_schannel_ctxt *)
+ calloc(1, sizeof(struct Curl_schannel_ctxt));
if(!BACKEND->ctxt) {
failf(data, "schannel: unable to allocate memory");
return CURLE_OUT_OF_MEMORY;
@@ -1178,6 +1181,10 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
failf(data, "schannel: SNI or certificate check failed: %s",
Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
return CURLE_PEER_FAILED_VERIFICATION;
+ case SEC_E_UNTRUSTED_ROOT:
+ failf(data, "schannel: %s",
+ Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
+ return CURLE_PEER_FAILED_VERIFICATION;
/*
case SEC_E_INVALID_HANDLE:
case SEC_E_INVALID_TOKEN:
@@ -1401,7 +1408,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
/* save the current session data for possible re-use */
if(SSL_SET_OPTION(primary.sessionid)) {
bool incache;
- struct curl_schannel_cred *old_cred = NULL;
+ struct Curl_schannel_cred *old_cred = NULL;
Curl_ssl_sessionid_lock(conn);
incache = !(Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL,
@@ -1417,7 +1424,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
}
if(!incache) {
result = Curl_ssl_addsessionid(conn, (void *)BACKEND->cred,
- sizeof(struct curl_schannel_cred),
+ sizeof(struct Curl_schannel_cred),
sockindex);
if(result) {
Curl_ssl_sessionid_unlock(conn);
@@ -2099,7 +2106,7 @@ static void Curl_schannel_close(struct connectdata *conn, int sockindex)
static void Curl_schannel_session_free(void *ptr)
{
/* this is expected to be called under sessionid lock */
- struct curl_schannel_cred *cred = ptr;
+ struct Curl_schannel_cred *cred = ptr;
cred->refcount--;
if(cred->refcount == 0) {
diff --git a/lib/vtls/schannel.h b/lib/vtls/schannel.h
index ee8d7d47a..085b3f455 100644
--- a/lib/vtls/schannel.h
+++ b/lib/vtls/schannel.h
@@ -8,11 +8,11 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012, Marc Hoersken, <info@marc-hoersken.de>, et al.
- * Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -70,20 +70,20 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex);
#endif
#endif
-struct curl_schannel_cred {
+struct Curl_schannel_cred {
CredHandle cred_handle;
TimeStamp time_stamp;
int refcount;
};
-struct curl_schannel_ctxt {
+struct Curl_schannel_ctxt {
CtxtHandle ctxt_handle;
TimeStamp time_stamp;
};
struct ssl_backend_data {
- struct curl_schannel_cred *cred;
- struct curl_schannel_ctxt *ctxt;
+ struct Curl_schannel_cred *cred;
+ struct Curl_schannel_ctxt *ctxt;
SecPkgContext_StreamSizes stream_sizes;
size_t encdata_length, decdata_length;
size_t encdata_offset, decdata_offset;
diff --git a/lib/vtls/schannel_verify.c b/lib/vtls/schannel_verify.c
index ab7be3950..31b3b2f02 100644
--- a/lib/vtls/schannel_verify.c
+++ b/lib/vtls/schannel_verify.c
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/sectransp.c b/lib/vtls/sectransp.c
index 2627aff16..8ef60cb1f 100644
--- a/lib/vtls/sectransp.c
+++ b/lib/vtls/sectransp.c
@@ -10,7 +10,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -1397,11 +1397,16 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn,
const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
const struct curl_blob *ssl_cablob = NULL;
const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
- char * const ssl_cert = SSL_SET_OPTION(cert);
- const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(cert_blob);
+ char * const ssl_cert = SSL_SET_OPTION(primary.clientcert);
+ const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob);
+#ifndef CURL_DISABLE_PROXY
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
+#else
+ const char * const hostname = conn->host.name;
+ const long int port = conn->remote_port;
+#endif
#ifdef ENABLE_IPV6
struct in6_addr addr;
#else
@@ -1606,8 +1611,11 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn,
&kCFTypeArrayCallBacks);
#ifdef USE_NGHTTP2
- if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
- (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) {
+ if(data->set.httpversion >= CURL_HTTP_VERSION_2
+#ifndef CURL_DISABLE_PROXY
+ && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
+#endif
+ ) {
CFArrayAppendValue(alpnArr, CFSTR(NGHTTP2_PROTO_VERSION_ID));
infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
}
@@ -1962,7 +1970,7 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn,
else {
CURLcode result;
ssl_sessionid =
- aprintf("%s:%d:%d:%s:%hu", ssl_cafile,
+ aprintf("%s:%d:%d:%s:%ld", ssl_cafile,
verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port);
ssl_sessionid_len = strlen(ssl_sessionid);
@@ -2181,7 +2189,7 @@ static CURLcode verify_cert(const char *cafile, struct Curl_easy *data,
if(res < 0) {
free(certbuf);
CFRelease(array);
- failf(data, "SSL: invalid CA certificate #%d (offset %d) in bundle",
+ failf(data, "SSL: invalid CA certificate #%d (offset %zu) in bundle",
n, offset);
return CURLE_SSL_CACERT_BADFILE;
}
@@ -2379,8 +2387,12 @@ sectransp_connect_step2(struct connectdata *conn, int sockindex)
OSStatus err;
SSLCipherSuite cipher;
SSLProtocol protocol = 0;
+#ifndef CURL_DISABLE_PROXY
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
+#else
+ const char * const hostname = conn->host.name;
+#endif
DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
|| ssl_connect_2_reading == connssl->connecting_state
diff --git a/lib/vtls/sectransp.h b/lib/vtls/sectransp.h
index 5cec797b3..0febd6613 100644
--- a/lib/vtls/sectransp.h
+++ b/lib/vtls/sectransp.h
@@ -8,11 +8,11 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>.
- * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c
index 281043aa6..3bd51fdaf 100644
--- a/lib/vtls/vtls.c
+++ b/lib/vtls/vtls.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -138,6 +138,7 @@ Curl_ssl_config_matches(struct ssl_primary_config *data,
Curl_safe_strcasecompare(data->egdsocket, needle->egdsocket) &&
Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) &&
Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13) &&
+ Curl_safe_strcasecompare(data->curves, needle->curves) &&
Curl_safe_strcasecompare(data->pinned_key, needle->pinned_key))
return TRUE;
@@ -164,6 +165,7 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
CLONE_STRING(cipher_list);
CLONE_STRING(cipher_list13);
CLONE_STRING(pinned_key);
+ CLONE_STRING(curves);
return TRUE;
}
@@ -179,6 +181,7 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc)
Curl_safefree(sslc->cipher_list13);
Curl_safefree(sslc->pinned_key);
Curl_safefree(sslc->cert_blob);
+ Curl_safefree(sslc->curves);
}
#ifdef USE_SSL
@@ -362,7 +365,7 @@ bool Curl_ssl_getsessionid(struct connectdata *conn,
size_t *idsize, /* set 0 if unknown */
int sockindex)
{
- struct curl_ssl_session *check;
+ struct Curl_ssl_session *check;
struct Curl_easy *data = conn->data;
size_t i;
long *general_age;
@@ -429,7 +432,7 @@ bool Curl_ssl_getsessionid(struct connectdata *conn,
/*
* Kill a single session ID entry in the cache.
*/
-void Curl_ssl_kill_session(struct curl_ssl_session *session)
+void Curl_ssl_kill_session(struct Curl_ssl_session *session)
{
if(session->sessionid) {
/* defensive check */
@@ -456,7 +459,7 @@ void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid)
struct Curl_easy *data = conn->data;
for(i = 0; i < data->set.general_ssl.max_ssl_sessions; i++) {
- struct curl_ssl_session *check = &data->state.session[i];
+ struct Curl_ssl_session *check = &data->state.session[i];
if(check->sessionid == ssl_sessionid) {
Curl_ssl_kill_session(check);
@@ -478,7 +481,7 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
{
size_t i;
struct Curl_easy *data = conn->data; /* the mother of all structs */
- struct curl_ssl_session *store = &data->state.session[0];
+ struct Curl_ssl_session *store = &data->state.session[0];
long oldest_age = data->state.session[0].age; /* zero if unused */
char *clone_host;
char *clone_conn_to_host;
@@ -664,13 +667,13 @@ struct curl_slist *Curl_ssl_engines_list(struct Curl_easy *data)
*/
CURLcode Curl_ssl_initsessions(struct Curl_easy *data, size_t amount)
{
- struct curl_ssl_session *session;
+ struct Curl_ssl_session *session;
if(data->state.session)
/* this is just a precaution to prevent multiple inits */
return CURLE_OK;
- session = calloc(amount, sizeof(struct curl_ssl_session));
+ session = calloc(amount, sizeof(struct Curl_ssl_session));
if(!session)
return CURLE_OUT_OF_MEMORY;
diff --git a/lib/vtls/vtls.h b/lib/vtls/vtls.h
index bcc844416..f4cab9988 100644
--- a/lib/vtls/vtls.h
+++ b/lib/vtls/vtls.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -131,12 +131,26 @@ CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen,
CURL_SOCKET_BAD ? FIRSTSOCKET : SECONDARYSOCKET].state)
#define SSL_SET_OPTION(var) \
(SSL_IS_PROXY() ? data->set.proxy_ssl.var : data->set.ssl.var)
+#define SSL_SET_OPTION_LVALUE(var) \
+ (*(SSL_IS_PROXY() ? &data->set.proxy_ssl.var : &data->set.ssl.var))
#define SSL_CONN_CONFIG(var) \
(SSL_IS_PROXY() ? conn->proxy_ssl_config.var : conn->ssl_config.var)
+#define SSL_HOST_NAME() \
+ (SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name)
+#define SSL_HOST_DISPNAME() \
+ (SSL_IS_PROXY() ? conn->http_proxy.host.dispname : conn->host.dispname)
+#define SSL_PINNED_PUB_KEY() (SSL_IS_PROXY() \
+ ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] \
+ : data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG])
#else
#define SSL_IS_PROXY() FALSE
#define SSL_SET_OPTION(var) data->set.ssl.var
+#define SSL_SET_OPTION_LVALUE(var) data->set.ssl.var
#define SSL_CONN_CONFIG(var) conn->ssl_config.var
+#define SSL_HOST_NAME() conn->host.name
+#define SSL_HOST_DISPNAME() conn->host.dispname
+#define SSL_PINNED_PUB_KEY() \
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]
#endif
bool Curl_ssl_config_matches(struct ssl_primary_config *data,
@@ -221,7 +235,7 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
* take sessionid object ownership from sessionid cache
* (e.g. decrement refcount).
*/
-void Curl_ssl_kill_session(struct curl_ssl_session *session);
+void Curl_ssl_kill_session(struct Curl_ssl_session *session);
/* delete a session from the cache
* Sessionid mutex must be locked (see Curl_ssl_sessionid_lock).
* This will call engine-specific curlssl_session_free function, which must
diff --git a/lib/vtls/wolfssl.c b/lib/vtls/wolfssl.c
index 7b2a124e4..44ee2d9ec 100644
--- a/lib/vtls/wolfssl.c
+++ b/lib/vtls/wolfssl.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -353,8 +353,8 @@ wolfssl_connect_step1(struct connectdata *conn,
SSL_CONN_CONFIG(CApath))) {
if(SSL_CONN_CONFIG(verifypeer)) {
/* Fail if we insist on successfully verifying the server. */
- failf(data, "error setting certificate verify locations:\n"
- " CAfile: %s\n CApath: %s",
+ failf(data, "error setting certificate verify locations:"
+ " CAfile: %s CApath: %s",
SSL_CONN_CONFIG(CAfile)?
SSL_CONN_CONFIG(CAfile): "none",
SSL_CONN_CONFIG(CApath)?
@@ -372,21 +372,19 @@ wolfssl_connect_step1(struct connectdata *conn,
/* Everything is fine. */
infof(data, "successfully set certificate verify locations:\n");
}
- infof(data,
- " CAfile: %s\n"
- " CApath: %s\n",
- SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile):
- "none",
- SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath):
- "none");
+ infof(data, " CAfile: %s\n",
+ SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile) : "none");
+ infof(data, " CApath: %s\n",
+ SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath) : "none");
}
/* Load the client certificate, and private key */
- if(SSL_SET_OPTION(cert) && SSL_SET_OPTION(key)) {
+ if(SSL_SET_OPTION(primary.clientcert) && SSL_SET_OPTION(key)) {
int file_type = do_file_type(SSL_SET_OPTION(cert_type));
- if(SSL_CTX_use_certificate_file(backend->ctx, SSL_SET_OPTION(cert),
- file_type) != 1) {
+ if(SSL_CTX_use_certificate_file(backend->ctx,
+ SSL_SET_OPTION(primary.clientcert),
+ file_type) != 1) {
failf(data, "unable to use client certificate (no key or wrong pass"
" phrase?)");
return CURLE_SSL_CONNECT_ERROR;
diff --git a/lib/vtls/wolfssl.h b/lib/vtls/wolfssl.h
index 2b9673c0f..d411e6913 100644
--- a/lib/vtls/wolfssl.h
+++ b/lib/vtls/wolfssl.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/warnless.c b/lib/warnless.c
index cfd5e8e14..908ee6cb7 100644
--- a/lib/warnless.c
+++ b/lib/warnless.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/warnless.h b/lib/warnless.h
index 42b012ed0..fd7f618ae 100644
--- a/lib/warnless.h
+++ b/lib/warnless.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/wildcard.c b/lib/wildcard.c
index e94d3c544..105bcce4e 100644
--- a/lib/wildcard.c
+++ b/lib/wildcard.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/wildcard.h b/lib/wildcard.h
index 306c8c99f..081be9ed9 100644
--- a/lib/wildcard.h
+++ b/lib/wildcard.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2010 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -39,18 +39,18 @@ typedef enum {
CURLWC_ERROR, /* error cases */
CURLWC_DONE /* if is wildcard->state == CURLWC_DONE wildcard loop
will end */
-} curl_wildcard_states;
+} wildcard_states;
-typedef void (*curl_wildcard_dtor)(void *ptr);
+typedef void (*wildcard_dtor)(void *ptr);
/* struct keeping information about wildcard download process */
struct WildcardData {
- curl_wildcard_states state;
+ wildcard_states state;
char *path; /* path to the directory, where we trying wildcard-match */
char *pattern; /* wildcard pattern */
- struct curl_llist filelist; /* llist with struct Curl_fileinfo */
+ struct Curl_llist filelist; /* llist with struct Curl_fileinfo */
void *protdata; /* pointer to protocol specific temporary data */
- curl_wildcard_dtor dtor;
+ wildcard_dtor dtor;
void *customptr; /* for CURLOPT_CHUNK_DATA pointer */
};
diff --git a/lib/x509asn1.c b/lib/x509asn1.c
index a0b167a94..336d2429a 100644
--- a/lib/x509asn1.c
+++ b/lib/x509asn1.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/lib/x509asn1.h b/lib/x509asn1.h
index 0b7fb8817..849714492 100644
--- a/lib/x509asn1.h
+++ b/lib/x509asn1.h
@@ -12,7 +12,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/libgnurl.pc.in b/libgnurl.pc.in
index c41c73026..b7ce570db 100644
--- a/libgnurl.pc.in
+++ b/libgnurl.pc.in
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -31,7 +31,7 @@ supported_protocols="@SUPPORT_PROTOCOLS@"
supported_features="@SUPPORT_FEATURES@"
Name: libgnurl
-URL: https://gnunet.org/gnurl/
+URL: https://gnunet.org/en/gnurl.html
Description: Library to transfer files with http or https
Version: @CURLVERSION@
Libs: -L${libdir} -lgnurl @LIBCURL_NO_SHARED@
diff --git a/m4/curl-compilers.m4 b/m4/curl-compilers.m4
index 107dc6ab9..59ac340c0 100644
--- a/m4/curl-compilers.m4
+++ b/m4/curl-compilers.m4
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -945,6 +945,10 @@ AC_DEFUN([CURL_SET_COMPILER_WARNING_OPTS], [
tmp_CFLAGS="$tmp_CFLAGS -Wno-varargs"
fi
fi
+ dnl clang 7 or later
+ if test "$compiler_num" -ge "700"; then
+ CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [assign-enum])
+ fi
fi
;;
#
@@ -1119,6 +1123,10 @@ AC_DEFUN([CURL_SET_COMPILER_WARNING_OPTS], [
fi
fi
fi
+ dnl Only gcc 10 or later
+ if test "$compiler_num" -ge "1000"; then
+ CURL_ADD_COMPILER_WARNINGS([tmp_CFLAGS], [enum-conversion])
+ fi
;;
#
HP_UX_C)
diff --git a/m4/curl-confopts.m4 b/m4/curl-confopts.m4
index 566db8ec5..99a9ad73e 100644
--- a/m4/curl-confopts.m4
+++ b/m4/curl-confopts.m4
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -651,37 +651,37 @@ AC_DEFUN([CURL_CHECK_NTLM_WB], [
fi
])
-dnl CURL_CHECK_OPTION_ESNI
+dnl CURL_CHECK_OPTION_ECH
dnl -----------------------------------------------------
dnl Verify whether configure has been invoked with option
-dnl --enable-esni or --disable-esni, and set
-dnl shell variable want_esni as appropriate.
-
-AC_DEFUN([CURL_CHECK_OPTION_ESNI], [
- AC_MSG_CHECKING([whether to enable ESNI support])
- OPT_ESNI="default"
- AC_ARG_ENABLE(esni,
-AC_HELP_STRING([--enable-esni],[Enable ESNI support])
-AC_HELP_STRING([--disable-esni],[Disable ESNI support]),
- OPT_ESNI=$enableval)
- case "$OPT_ESNI" in
+dnl --enable-ech or --disable-ech, and set
+dnl shell variable want_ech as appropriate.
+
+AC_DEFUN([CURL_CHECK_OPTION_ECH], [
+ AC_MSG_CHECKING([whether to enable ECH support])
+ OPT_ECH="default"
+ AC_ARG_ENABLE(ech,
+AC_HELP_STRING([--enable-ech],[Enable ECH support])
+AC_HELP_STRING([--disable-ech],[Disable ECH support]),
+ OPT_ECH=$enableval)
+ case "$OPT_ECH" in
no)
- dnl --disable-esni option used
- want_esni="no"
- curl_esni_msg="no (--enable-esni)"
+ dnl --disable-ech option used
+ want_ech="no"
+ curl_ech_msg="no (--enable-ech)"
AC_MSG_RESULT([no])
;;
default)
dnl configure option not specified
- want_esni="no"
- curl_esni_msg="no (--enable-esni)"
+ want_ech="no"
+ curl_ech_msg="no (--enable-ech)"
AC_MSG_RESULT([no])
;;
*)
- dnl --enable-esni option used
- want_esni="yes"
- curl_esni_msg="enabled (--disable-esni)"
- experimental="esni"
+ dnl --enable-ech option used
+ want_ech="yes"
+ curl_ech_msg="enabled (--disable-ech)"
+ experimental="ech"
AC_MSG_RESULT([yes])
;;
esac
diff --git a/m4/curl-functions.m4 b/m4/curl-functions.m4
index b4e64cf33..58a3cf443 100644
--- a/m4/curl-functions.m4
+++ b/m4/curl-functions.m4
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/m4/curl-openssl.m4 b/m4/curl-openssl.m4
index 24f33aa11..159dc3e24 100644
--- a/m4/curl-openssl.m4
+++ b/m4/curl-openssl.m4
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/m4/curl-override.m4 b/m4/curl-override.m4
index 18e4e2091..72fc393a8 100644
--- a/m4/curl-override.m4
+++ b/m4/curl-override.m4
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/m4/curl-reentrant.m4 b/m4/curl-reentrant.m4
index 32cbaf854..94e76b688 100644
--- a/m4/curl-reentrant.m4
+++ b/m4/curl-reentrant.m4
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/maketgz b/maketgz
index cafd4f7e9..2bf648b15 100755
--- a/maketgz
+++ b/maketgz
@@ -9,11 +9,11 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/packages/Android/Android.mk b/packages/Android/Android.mk
index adb6336fe..2e52c75f4 100644
--- a/packages/Android/Android.mk
+++ b/packages/Android/Android.mk
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/packages/DOS/common.dj b/packages/DOS/common.dj
index b0e15d676..0eecd8a62 100644
--- a/packages/DOS/common.dj
+++ b/packages/DOS/common.dj
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/packages/Makefile.am b/packages/Makefile.am
index d8a92abbb..56b1ae404 100644
--- a/packages/Makefile.am
+++ b/packages/Makefile.am
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -37,17 +37,15 @@ EXTRA_DIST = README \
OS400/makefile.sh \
OS400/os400sys.c \
OS400/os400sys.h \
- Symbian/bwins/libcurlu.def \
- Symbian/eabi/libcurlu.def \
- Symbian/group/bld.inf \
- Symbian/group/curl.iby \
- Symbian/group/curl.mmp \
- Symbian/group/curl.pkg \
- Symbian/group/libcurl.iby \
- Symbian/group/libcurl.mmp \
- Symbian/group/libcurl.pkg \
- Symbian/readme.txt \
TPF/curl.mak \
TPF/maketpf.env_curl \
TPF/maketpf.env_curllib \
Android/Android.mk
+
+CHECKSRC = $(CS_$(V))
+CS_0 = @echo " RUN " $@;
+CS_1 =
+CS_ = $(CS_0)
+
+checksrc:
+ $(CHECKSRC)(@PERL@ $(top_srcdir)/lib/checksrc.pl -D$(srcdir) $(srcdir)/OS400/*.[ch])
diff --git a/packages/OS400/ccsidcurl.c b/packages/OS400/ccsidcurl.c
index 4e04927b0..3ff923ebf 100644
--- a/packages/OS400/ccsidcurl.c
+++ b/packages/OS400/ccsidcurl.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -57,7 +57,6 @@
static void
makeOS400IconvCode(char buf[ICONV_ID_SIZE], unsigned int ccsid)
-
{
/**
*** Convert a CCSID to the corresponding IBM iconv_open() character
@@ -79,8 +78,7 @@ makeOS400IconvCode(char buf[ICONV_ID_SIZE], unsigned int ccsid)
static iconv_t
iconv_open_CCSID(unsigned int ccsidout, unsigned int ccsidin,
- unsigned int cstr)
-
+ unsigned int cstr)
{
char fromcode[ICONV_ID_SIZE];
char tocode[ICONV_ID_SIZE];
@@ -106,7 +104,6 @@ iconv_open_CCSID(unsigned int ccsidout, unsigned int ccsidin,
static int
convert(char *d, size_t dlen, int dccsid,
const char *s, int slen, int sccsid)
-
{
int i;
iconv_t cd;
@@ -160,9 +157,7 @@ convert(char *d, size_t dlen, int dccsid,
}
-static char *
-dynconvert(int dccsid, const char *s, int slen, int sccsid)
-
+static char *dynconvert(int dccsid, const char *s, int slen, int sccsid)
{
char *d;
char *cp;
@@ -214,7 +209,6 @@ dynconvert(int dccsid, const char *s, int slen, int sccsid)
static struct curl_slist *
slist_convert(int dccsid, struct curl_slist *from, int sccsid)
-
{
struct curl_slist *to = (struct curl_slist *) NULL;
@@ -238,9 +232,7 @@ slist_convert(int dccsid, struct curl_slist *from, int sccsid)
}
-char *
-curl_version_ccsid(unsigned int ccsid)
-
+char *curl_version_ccsid(unsigned int ccsid)
{
int i;
char *aversion;
@@ -268,7 +260,6 @@ curl_version_ccsid(unsigned int ccsid)
char *
curl_easy_escape_ccsid(CURL *handle, const char *string, int length,
unsigned int sccsid, unsigned int dccsid)
-
{
char *s;
char *d;
@@ -299,7 +290,6 @@ char *
curl_easy_unescape_ccsid(CURL *handle, const char *string, int length,
int *outlength,
unsigned int sccsid, unsigned int dccsid)
-
{
char *s;
char *d;
@@ -333,7 +323,6 @@ curl_easy_unescape_ccsid(CURL *handle, const char *string, int length,
struct curl_slist *
curl_slist_append_ccsid(struct curl_slist *list,
const char *data, unsigned int ccsid)
-
{
char *s;
@@ -355,7 +344,6 @@ curl_slist_append_ccsid(struct curl_slist *list,
time_t
curl_getdate_ccsid(const char *p, const time_t * unused, unsigned int ccsid)
-
{
char *s;
time_t t;
@@ -377,7 +365,6 @@ curl_getdate_ccsid(const char *p, const time_t * unused, unsigned int ccsid)
static int
convert_version_info_string(const char * * stringp,
char * * bufp, int *left, unsigned int ccsid)
-
{
/* Helper for curl_version_info_ccsid(): convert a string if defined.
Result is stored in the `*left'-byte buffer at `*bufp'.
@@ -401,13 +388,12 @@ convert_version_info_string(const char * * stringp,
curl_version_info_data *
curl_version_info_ccsid(CURLversion stamp, unsigned int ccsid)
-
{
- curl_version_info_data * p;
+ curl_version_info_data *p;
char *cp;
int n;
int nproto;
- curl_version_info_data * id;
+ curl_version_info_data *id;
/* The assertion below is possible, because although the second operand
is an enum member, the first is a #define. In that case, the OS/400 C
@@ -519,7 +505,6 @@ curl_version_info_ccsid(CURLversion stamp, unsigned int ccsid)
const char *
curl_easy_strerror_ccsid(CURLcode error, unsigned int ccsid)
-
{
int i;
const char *s;
@@ -545,7 +530,6 @@ curl_easy_strerror_ccsid(CURLcode error, unsigned int ccsid)
const char *
curl_share_strerror_ccsid(CURLSHcode error, unsigned int ccsid)
-
{
int i;
const char *s;
@@ -571,7 +555,6 @@ curl_share_strerror_ccsid(CURLSHcode error, unsigned int ccsid)
const char *
curl_multi_strerror_ccsid(CURLMcode error, unsigned int ccsid)
-
{
int i;
const char *s;
@@ -597,7 +580,6 @@ curl_multi_strerror_ccsid(CURLMcode error, unsigned int ccsid)
void
curl_certinfo_free_all(struct curl_certinfo *info)
-
{
/* Free all memory used by certificate info. */
if(info) {
@@ -615,12 +597,11 @@ curl_certinfo_free_all(struct curl_certinfo *info)
CURLcode
curl_easy_getinfo_ccsid(CURL *curl, CURLINFO info, ...)
-
{
va_list arg;
void *paramp;
CURLcode ret;
- struct Curl_easy * data;
+ struct Curl_easy *data;
/* WARNING: unlike curl_easy_getinfo(), the strings returned by this
procedure have to be free'ed. */
@@ -716,7 +697,6 @@ curl_easy_getinfo_ccsid(CURL *curl, CURLINFO info, ...)
static int
Curl_is_formadd_string(CURLformoption option)
-
{
switch(option) {
@@ -735,8 +715,7 @@ Curl_is_formadd_string(CURLformoption option)
static void
-Curl_formadd_release_local(struct curl_forms * forms, int nargs, int skip)
-
+Curl_formadd_release_local(struct curl_forms *forms, int nargs, int skip)
{
while(nargs--)
if(nargs != skip)
@@ -749,9 +728,8 @@ Curl_formadd_release_local(struct curl_forms * forms, int nargs, int skip)
static int
-Curl_formadd_convert(struct curl_forms * forms,
+Curl_formadd_convert(struct curl_forms *forms,
int formx, int lengthx, unsigned int ccsid)
-
{
int l;
char *cp;
@@ -795,14 +773,13 @@ Curl_formadd_convert(struct curl_forms * forms,
CURLFORMcode
curl_formadd_ccsid(struct curl_httppost * * httppost,
struct curl_httppost * * last_post, ...)
-
{
va_list arg;
CURLformoption option;
CURLFORMcode result;
- struct curl_forms * forms;
- struct curl_forms * lforms;
- struct curl_forms * tforms;
+ struct curl_forms *forms;
+ struct curl_forms *lforms;
+ struct curl_forms *tforms;
unsigned int lformlen;
const char *value;
unsigned int ccsid;
@@ -1066,18 +1043,17 @@ curl_formadd_ccsid(struct curl_httppost * * httppost,
}
-typedef struct {
+struct cfcdata {
curl_formget_callback append;
void * arg;
unsigned int ccsid;
-} cfcdata;
+};
static size_t
Curl_formget_callback_ccsid(void *arg, const char *buf, size_t len)
-
{
- cfcdata * p;
+ struct cfcdata *p;
char *b;
int l;
size_t ret;
@@ -1108,7 +1084,6 @@ Curl_formget_callback_ccsid(void *arg, const char *buf, size_t len)
int
curl_formget_ccsid(struct curl_httppost *form, void *arg,
curl_formget_callback append, unsigned int ccsid)
-
{
cfcdata lcfc;
@@ -1121,7 +1096,6 @@ curl_formget_ccsid(struct curl_httppost *form, void *arg,
CURLcode
curl_easy_setopt_ccsid(CURL *curl, CURLoption tag, ...)
-
{
CURLcode result;
va_list arg;
@@ -1208,6 +1182,7 @@ curl_easy_setopt_ccsid(CURL *curl, CURLoption tag, ...)
case CURLOPT_SSLKEY:
case CURLOPT_SSLKEYTYPE:
case CURLOPT_SSL_CIPHER_LIST:
+ case CURLOPT_SSL_EC_CURVES:
case CURLOPT_TLS13_CIPHERS:
case CURLOPT_TLSAUTH_PASSWORD:
case CURLOPT_TLSAUTH_TYPE:
@@ -1308,7 +1283,6 @@ curl_easy_setopt_ccsid(CURL *curl, CURLoption tag, ...)
char *
curl_form_long_value(long value)
-
{
/* ILE/RPG cannot cast an integer to a pointer. This procedure does it. */
@@ -1319,7 +1293,6 @@ curl_form_long_value(long value)
char *
curl_pushheader_bynum_cssid(struct curl_pushheaders *h,
size_t num, unsigned int ccsid)
-
{
char *d = (char *) NULL;
char *s = curl_pushheader_bynum(h, num);
@@ -1334,7 +1307,6 @@ curl_pushheader_bynum_cssid(struct curl_pushheaders *h,
char *
curl_pushheader_byname_ccsid(struct curl_pushheaders *h, const char *header,
unsigned int ccsidin, unsigned int ccsidout)
-
{
char *d = (char *) NULL;
@@ -1356,7 +1328,6 @@ curl_pushheader_byname_ccsid(struct curl_pushheaders *h, const char *header,
static CURLcode
mime_string_call(curl_mimepart *part, const char *string, unsigned int ccsid,
CURLcode (*mimefunc)(curl_mimepart *part, const char *string))
-
{
char *s = (char *) NULL;
CURLcode result;
@@ -1374,7 +1345,6 @@ mime_string_call(curl_mimepart *part, const char *string, unsigned int ccsid,
CURLcode
curl_mime_name_ccsid(curl_mimepart *part, const char *name, unsigned int ccsid)
-
{
return mime_string_call(part, name, ccsid, curl_mime_name);
}
@@ -1382,7 +1352,6 @@ curl_mime_name_ccsid(curl_mimepart *part, const char *name, unsigned int ccsid)
CURLcode
curl_mime_filename_ccsid(curl_mimepart *part,
const char *filename, unsigned int ccsid)
-
{
return mime_string_call(part, filename, ccsid, curl_mime_filename);
}
@@ -1390,7 +1359,6 @@ curl_mime_filename_ccsid(curl_mimepart *part,
CURLcode
curl_mime_type_ccsid(curl_mimepart *part,
const char *mimetype, unsigned int ccsid)
-
{
return mime_string_call(part, mimetype, ccsid, curl_mime_type);
}
@@ -1398,7 +1366,6 @@ curl_mime_type_ccsid(curl_mimepart *part,
CURLcode
curl_mime_encoder_ccsid(curl_mimepart *part,
const char *encoding, unsigned int ccsid)
-
{
return mime_string_call(part, encoding, ccsid, curl_mime_encoder);
}
@@ -1406,7 +1373,6 @@ curl_mime_encoder_ccsid(curl_mimepart *part,
CURLcode
curl_mime_filedata_ccsid(curl_mimepart *part,
const char *filename, unsigned int ccsid)
-
{
return mime_string_call(part, filename, ccsid, curl_mime_filedata);
}
@@ -1414,7 +1380,6 @@ curl_mime_filedata_ccsid(curl_mimepart *part,
CURLcode
curl_mime_data_ccsid(curl_mimepart *part,
const char *data, size_t datasize, unsigned int ccsid)
-
{
char *s = (char *) NULL;
CURLcode result;
@@ -1433,7 +1398,6 @@ curl_mime_data_ccsid(curl_mimepart *part,
CURLUcode
curl_url_get_ccsid(CURLU *handle, CURLUPart what, char **part,
unsigned int flags, unsigned int ccsid)
-
{
char *s = (char *)NULL;
CURLUcode result;
@@ -1458,7 +1422,6 @@ curl_url_get_ccsid(CURLU *handle, CURLUPart what, char **part,
CURLUcode
curl_url_set_ccsid(CURLU *handle, CURLUPart what, const char *part,
unsigned int flags, unsigned int ccsid)
-
{
char *s = (char *)NULL;
CURLUcode result;
diff --git a/packages/OS400/ccsidcurl.h b/packages/OS400/ccsidcurl.h
index 9594f6610..dd7e59eb4 100644
--- a/packages/OS400/ccsidcurl.h
+++ b/packages/OS400/ccsidcurl.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -27,37 +27,37 @@
#include "multi.h"
-CURL_EXTERN char * curl_version_ccsid(unsigned int ccsid);
-CURL_EXTERN char * curl_easy_escape_ccsid(CURL * handle,
- const char * string, int length,
- unsigned int sccsid,
- unsigned int dccsid);
-CURL_EXTERN char * curl_easy_unescape_ccsid(CURL * handle, const char * string,
- int length, int * outlength,
- unsigned int sccsid,
- unsigned int dccsid);
-CURL_EXTERN struct curl_slist * curl_slist_append_ccsid(struct curl_slist * l,
- const char * data,
- unsigned int ccsid);
-CURL_EXTERN time_t curl_getdate_ccsid(const char * p, const time_t * unused,
+CURL_EXTERN char *curl_version_ccsid(unsigned int ccsid);
+CURL_EXTERN char *curl_easy_escape_ccsid(CURL *handle,
+ const char *string, int length,
+ unsigned int sccsid,
+ unsigned int dccsid);
+CURL_EXTERN char *curl_easy_unescape_ccsid(CURL *handle, const char *string,
+ int length, int *outlength,
+ unsigned int sccsid,
+ unsigned int dccsid);
+CURL_EXTERN struct curl_slist *curl_slist_append_ccsid(struct curl_slist *l,
+ const char *data,
+ unsigned int ccsid);
+CURL_EXTERN time_t curl_getdate_ccsid(const char *p, const time_t *unused,
unsigned int ccsid);
-CURL_EXTERN curl_version_info_data * curl_version_info_ccsid(CURLversion stamp,
- unsigned int cid);
-CURL_EXTERN const char * curl_easy_strerror_ccsid(CURLcode error,
+CURL_EXTERN curl_version_info_data *curl_version_info_ccsid(CURLversion stamp,
+ unsigned int cid);
+CURL_EXTERN const char *curl_easy_strerror_ccsid(CURLcode error,
+ unsigned int ccsid);
+CURL_EXTERN const char *curl_share_strerror_ccsid(CURLSHcode error,
unsigned int ccsid);
-CURL_EXTERN const char * curl_share_strerror_ccsid(CURLSHcode error,
- unsigned int ccsid);
-CURL_EXTERN const char * curl_multi_strerror_ccsid(CURLMcode error,
- unsigned int ccsid);
-CURL_EXTERN CURLcode curl_easy_getinfo_ccsid(CURL * curl, CURLINFO info, ...);
-CURL_EXTERN CURLFORMcode curl_formadd_ccsid(struct curl_httppost * * httppost,
- struct curl_httppost * * last_post,
+CURL_EXTERN const char *curl_multi_strerror_ccsid(CURLMcode error,
+ unsigned int ccsid);
+CURL_EXTERN CURLcode curl_easy_getinfo_ccsid(CURL *curl, CURLINFO info, ...);
+CURL_EXTERN CURLFORMcode curl_formadd_ccsid(struct curl_httppost **httppost,
+ struct curl_httppost **last_post,
...);
-CURL_EXTERN char * curl_form_long_value(long value);
-CURL_EXTERN int curl_formget_ccsid(struct curl_httppost * form, void * arg,
+CURL_EXTERN char *curl_form_long_value(long value);
+CURL_EXTERN int curl_formget_ccsid(struct curl_httppost *form, void *arg,
curl_formget_callback append,
unsigned int ccsid);
-CURL_EXTERN CURLcode curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...);
+CURL_EXTERN CURLcode curl_easy_setopt_ccsid(CURL *curl, CURLoption tag, ...);
CURL_EXTERN void curl_certinfo_free_all(struct curl_certinfo *info);
CURL_EXTERN char *curl_pushheader_bynum_cssid(struct curl_pushheaders *h,
size_t num, unsigned int ccsid);
diff --git a/packages/OS400/chkstrings.c b/packages/OS400/chkstrings.c
index 083263640..caa0ecab5 100644
--- a/packages/OS400/chkstrings.c
+++ b/packages/OS400/chkstrings.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -25,38 +25,38 @@
#include "curl_setup.h"
#include "urldata.h"
-/* The following defines indicate the expected dupstring enum values
- * in curl_easy_setopt_ccsid() in packages/OS400/ccsidcurl.c. If a
- * mismatch is flagged during the build, it indicates that curl_easy_setopt_ccsid()
- * may need updating to perform data EBCDIC to ASCII data conversion on
- * the string.
+/* The following defines indicate the expected dupstring enum values in
+ * curl_easy_setopt_ccsid() in packages/OS400/ccsidcurl.c. If a mismatch is
+ * flagged during the build, it indicates that curl_easy_setopt_ccsid() may
+ * need updating to perform data EBCDIC to ASCII data conversion on the
+ * string.
+ *
* Once any applicable changes to curl_easy_setopt_ccsid() have been
* made, the EXPECTED_STRING_LASTZEROTERMINATED/EXPECTED_STRING_LAST
* values can be updated to match the latest enum values in urldata.h.
*/
-#define EXPECTED_STRING_LASTZEROTERMINATED (STRING_DNS_LOCAL_IP6 + 1)
+#define EXPECTED_STRING_LASTZEROTERMINATED (STRING_SSL_EC_CURVES + 1)
#define EXPECTED_STRING_LAST (STRING_COPYPOSTFIELDS + 1)
int main(int argc, char *argv[])
{
int rc = 0;
- if (STRING_LASTZEROTERMINATED != EXPECTED_STRING_LASTZEROTERMINATED)
- {
- fprintf(stderr,"STRING_LASTZEROTERMINATED(%d) is not expected value(%d).\n",
+ if(STRING_LASTZEROTERMINATED != EXPECTED_STRING_LASTZEROTERMINATED) {
+ fprintf(stderr,
+ "STRING_LASTZEROTERMINATED(%d) is not expected value(%d).\n",
STRING_LASTZEROTERMINATED, EXPECTED_STRING_LASTZEROTERMINATED);
rc += 1;
}
- if (STRING_LAST != EXPECTED_STRING_LAST)
- {
- fprintf(stderr,"STRING_LAST(%d) is not expected value(%d).\n",
+ if(STRING_LAST != EXPECTED_STRING_LAST) {
+ fprintf(stderr, "STRING_LAST(%d) is not expected value(%d).\n",
STRING_LAST, EXPECTED_STRING_LAST);
rc += 2;
}
- if (rc != 0)
- {
- fprintf(stderr,"curl_easy_setopt_ccsid() in packages/OS400/ccsidcurl.c"
- " may need updating if new strings are provided as input via the curl API.\n");
+ if(rc) {
+ fprintf(stderr, "curl_easy_setopt_ccsid() in packages/OS400/ccsidcurl.c"
+ " may need updating if new strings are provided as"
+ " input via the curl API.\n");
}
return rc;
}
diff --git a/packages/OS400/curl.inc.in b/packages/OS400/curl.inc.in
index 33ac8b34b..461184ead 100644
--- a/packages/OS400/curl.inc.in
+++ b/packages/OS400/curl.inc.in
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -236,6 +236,8 @@
d c 20000
d CURLOPTTYPE_OFF_T...
d c 30000
+ d CURLOPTTYPE_BLOB...
+ d c 40000
*
d CURL_IPRESOLVE_WHATEVER...
d c 0
@@ -1436,6 +1438,24 @@
d c 00288
d CURLOPT_SASL_AUTHZID...
d c 10289
+ d CURLOPT_MAIL_RCPT_ALLLOWFAILS...
+ d c 00290
+ d CURLOPT_SSLCERT_BLOB...
+ d c 40291
+ d CURLOPT_SSLKEY_BLOB...
+ d c 40292
+ d CURLOPT_PROXY_SSLCERT_BLOB...
+ d c 40293
+ d CURLOPT_PROXY_SSLKEY_BLOB...
+ d c 40294
+ d CURLOPT_ISSUERCERT_BLOB...
+ d c 40295
+ d CURLOPT_PROXY_ISSUERCERT...
+ d c 10296
+ d CURLOPT_PROXY_ISSUERCERT_BLOB...
+ d c 40297
+ d CURLOPT_SSL_EC_CURVES...
+ d c 10298
*
/if not defined(CURL_NO_OLDIES)
d CURLOPT_FILE c 10001
@@ -1655,7 +1675,13 @@
d CURLINFO_REDIRECT_TIME_T... CURLINFO_OFF_T + 55
d c X'00600037'
d CURLINFO_APPCONNECT_TIME_T... CURLINFO_OFF_T + 56
- d c X'00600036'
+ d c X'00600038'
+ d CURLINFO_RETRY_AFTER... CURLINFO_OFF_T + 57
+ d c X'00600039'
+ d CURLINFO_EFFECTIVE_METHOD... CURLINFO_STRING + 58
+ d c X'0010003A'
+ d CURLINFO_PROXY_ERROR... CURLINFO_LONG + 59
+ d c X'0020003B'
*
d CURLINFO_HTTP_CODE... Old ...RESPONSE_CODE
d c X'00200002'
diff --git a/packages/OS400/initscript.sh b/packages/OS400/initscript.sh
index 6ae7e6e11..22c14cd7c 100644
--- a/packages/OS400/initscript.sh
+++ b/packages/OS400/initscript.sh
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/packages/OS400/make-include.sh b/packages/OS400/make-include.sh
index 336e6ae65..d95eaa59c 100644
--- a/packages/OS400/make-include.sh
+++ b/packages/OS400/make-include.sh
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/packages/OS400/make-lib.sh b/packages/OS400/make-lib.sh
index 20e190245..b6f641188 100644
--- a/packages/OS400/make-lib.sh
+++ b/packages/OS400/make-lib.sh
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/packages/OS400/make-src.sh b/packages/OS400/make-src.sh
index dbe039b2c..8e7ad6d3d 100644
--- a/packages/OS400/make-src.sh
+++ b/packages/OS400/make-src.sh
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/packages/OS400/make-tests.sh b/packages/OS400/make-tests.sh
index 54cdd2fea..078b0f196 100644
--- a/packages/OS400/make-tests.sh
+++ b/packages/OS400/make-tests.sh
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/packages/OS400/makefile.sh b/packages/OS400/makefile.sh
index 29ba506e0..bfc56da3d 100644
--- a/packages/OS400/makefile.sh
+++ b/packages/OS400/makefile.sh
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/packages/OS400/os400sys.c b/packages/OS400/os400sys.c
index 445141eec..3c064905e 100644
--- a/packages/OS400/os400sys.c
+++ b/packages/OS400/os400sys.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -60,78 +60,70 @@
#include "os400sys.h"
-
/**
-*** QADRT OS/400 ASCII runtime defines only the most used procedures, but
-*** but a lot of them are not supported. This module implements
-*** ASCII wrappers for those that are used by libcurl, but not
-*** defined by QADRT.
+*** QADRT OS/400 ASCII runtime defines only the most used procedures, but a
+*** lot of them are not supported. This module implements ASCII wrappers for
+*** those that are used by libcurl, but not defined by QADRT.
**/
#pragma convert(0) /* Restore EBCDIC. */
-
#define MIN_BYTE_GAIN 1024 /* Minimum gain when shortening a buffer. */
-typedef struct {
- unsigned long size; /* Buffer size. */
- char * buf; /* Buffer address. */
-} buffer_t;
+struct buffer_t {
+ unsigned long size; /* Buffer size. */
+ char *buf; /* Buffer address. */
+};
-static char * buffer_undef(localkey_t key, long size);
-static char * buffer_threaded(localkey_t key, long size);
-static char * buffer_unthreaded(localkey_t key, long size);
+static char *buffer_undef(localkey_t key, long size);
+static char *buffer_threaded(localkey_t key, long size);
+static char *buffer_unthreaded(localkey_t key, long size);
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_key_t thdkey;
-static buffer_t * locbufs;
-
-char * (* Curl_thread_buffer)(localkey_t key, long size) = buffer_undef;
+static struct buffer_t *locbufs;
+char *(*Curl_thread_buffer)(localkey_t key, long size) = buffer_undef;
-static void
-thdbufdestroy(void * private)
-
+static void thdbufdestroy(void *private)
{
if(private) {
- buffer_t * p = (buffer_t *) private;
+ struct buffer_t *p = (struct buffer_t *) private;
localkey_t i;
for(i = (localkey_t) 0; i < LK_LAST; i++) {
free(p->buf);
p++;
- }
+ }
free(private);
- }
+ }
}
static void
terminate(void)
-
{
if(Curl_thread_buffer == buffer_threaded) {
locbufs = pthread_getspecific(thdkey);
pthread_setspecific(thdkey, (void *) NULL);
pthread_key_delete(thdkey);
- }
+ }
if(Curl_thread_buffer != buffer_undef) {
thdbufdestroy((void *) locbufs);
- locbufs = (buffer_t *) NULL;
- }
+ locbufs = (struct buffer_t *) NULL;
+ }
Curl_thread_buffer = buffer_undef;
}
static char *
-get_buffer(buffer_t * buf, long size)
-
+get_buffer(struct buffer_t *buf, long size)
{
- char * cp;
+ char *cp;
/* If `size' >= 0, make sure buffer at `buf' is at least `size'-byte long.
Return the buffer address. */
@@ -171,7 +163,6 @@ get_buffer(buffer_t * buf, long size)
static char *
buffer_unthreaded(localkey_t key, long size)
-
{
return get_buffer(locbufs + key, size);
}
@@ -179,15 +170,14 @@ buffer_unthreaded(localkey_t key, long size)
static char *
buffer_threaded(localkey_t key, long size)
-
{
- buffer_t * bufs;
+ struct buffer_t *bufs;
/* Get the buffer for the given local key in the current thread, and
make sure it is at least `size'-byte long. Set `size' to < 0 to get
its address only. */
- bufs = (buffer_t *) pthread_getspecific(thdkey);
+ bufs = (struct buffer_t *) pthread_getspecific(thdkey);
if(!bufs) {
if(size < 0)
@@ -211,7 +201,6 @@ buffer_threaded(localkey_t key, long size)
static char *
buffer_undef(localkey_t key, long size)
-
{
/* Define the buffer system, get the buffer for the given local key in
the current thread, and make sure it is at least `size'-byte long.
@@ -224,15 +213,18 @@ buffer_undef(localkey_t key, long size)
if(Curl_thread_buffer == buffer_undef) { /* If unchanged during lock. */
if(!pthread_key_create(&thdkey, thdbufdestroy))
Curl_thread_buffer = buffer_threaded;
- else if(!(locbufs = calloc((size_t) LK_LAST, sizeof(*locbufs)))) {
- pthread_mutex_unlock(&mutex);
- return (char *) NULL;
+ else {
+ locbufs = calloc((size_t) LK_LAST, sizeof(*locbufs));
+ if(!locbufs) {
+ pthread_mutex_unlock(&mutex);
+ return (char *) NULL;
}
- else
+ else
Curl_thread_buffer = buffer_unthreaded;
+ }
atexit(terminate);
- }
+ }
pthread_mutex_unlock(&mutex);
return Curl_thread_buffer(key, size);
@@ -240,11 +232,10 @@ buffer_undef(localkey_t key, long size)
static char *
-set_thread_string(localkey_t key, const char * s)
-
+set_thread_string(localkey_t key, const char *s)
{
int i;
- char * cp;
+ char *cp;
if(!s)
return (char *) NULL;
@@ -262,11 +253,10 @@ set_thread_string(localkey_t key, const char * s)
int
-Curl_getnameinfo_a(const struct sockaddr * sa, curl_socklen_t salen,
- char * nodename, curl_socklen_t nodenamelen,
- char * servname, curl_socklen_t servnamelen,
- int flags)
-
+Curl_getnameinfo_a(const struct sockaddr *sa, curl_socklen_t salen,
+ char *nodename, curl_socklen_t nodenamelen,
+ char *servname, curl_socklen_t servnamelen,
+ int flags)
{
char *enodename = NULL;
char *eservname = NULL;
@@ -293,31 +283,29 @@ Curl_getnameinfo_a(const struct sockaddr * sa, curl_socklen_t salen,
int i;
if(enodename) {
i = QadrtConvertE2A(nodename, enodename,
- nodenamelen - 1, strlen(enodename));
+ nodenamelen - 1, strlen(enodename));
nodename[i] = '\0';
- }
+ }
if(eservname) {
i = QadrtConvertE2A(servname, eservname,
- servnamelen - 1, strlen(eservname));
+ servnamelen - 1, strlen(eservname));
servname[i] = '\0';
- }
}
+ }
free(enodename);
free(eservname);
return status;
}
-
int
-Curl_getaddrinfo_a(const char * nodename, const char * servname,
- const struct addrinfo * hints,
- struct addrinfo * * res)
-
+Curl_getaddrinfo_a(const char *nodename, const char *servname,
+ const struct addrinfo *hints,
+ struct addrinfo **res)
{
- char * enodename;
- char * eservname;
+ char *enodename;
+ char *eservname;
int status;
int i;
@@ -354,7 +342,6 @@ Curl_getaddrinfo_a(const char * nodename, const char * servname,
return status;
}
-
#ifdef USE_GSKIT
/* ASCII wrappers for the GSKit procedures. */
@@ -370,22 +357,19 @@ Curl_getaddrinfo_a(const char * nodename, const char * servname,
*/
struct gskstrlist {
- struct gskstrlist * next;
- const char * ebcdicstr;
- const char * asciistr;
+ struct gskstrlist *next;
+ const char *ebcdicstr;
+ const char *asciistr;
};
struct Curl_gsk_descriptor {
gsk_handle h;
- struct gskstrlist * strlist;
+ struct gskstrlist *strlist;
};
-
-int
-Curl_gsk_environment_open(gsk_handle * my_env_handle)
-
+int Curl_gsk_environment_open(gsk_handle *my_env_handle)
{
- struct Curl_gsk_descriptor * p;
+ struct Curl_gsk_descriptor *p;
int rc;
if(!my_env_handle)
@@ -402,13 +386,10 @@ Curl_gsk_environment_open(gsk_handle * my_env_handle)
return rc;
}
-
-int
-Curl_gsk_secure_soc_open(gsk_handle my_env_handle,
- gsk_handle * my_session_handle)
-
+int Curl_gsk_secure_soc_open(gsk_handle my_env_handle,
+ gsk_handle *my_session_handle)
{
- struct Curl_gsk_descriptor * p;
+ struct Curl_gsk_descriptor *p;
gsk_handle h;
int rc;
@@ -429,12 +410,9 @@ Curl_gsk_secure_soc_open(gsk_handle my_env_handle,
return rc;
}
-
-static void
-gsk_free_handle(struct Curl_gsk_descriptor * p)
-
+static void gsk_free_handle(struct Curl_gsk_descriptor *p)
{
- struct gskstrlist * q;
+ struct gskstrlist *q;
while((q = p->strlist)) {
p->strlist = q;
@@ -444,12 +422,9 @@ gsk_free_handle(struct Curl_gsk_descriptor * p)
free(p);
}
-
-int
-Curl_gsk_environment_close(gsk_handle * my_env_handle)
-
+int Curl_gsk_environment_close(gsk_handle *my_env_handle)
{
- struct Curl_gsk_descriptor * p;
+ struct Curl_gsk_descriptor *p;
int rc;
if(!my_env_handle)
@@ -466,11 +441,9 @@ Curl_gsk_environment_close(gsk_handle * my_env_handle)
}
-int
-Curl_gsk_secure_soc_close(gsk_handle * my_session_handle)
-
+int Curl_gsk_secure_soc_close(gsk_handle *my_session_handle)
{
- struct Curl_gsk_descriptor * p;
+ struct Curl_gsk_descriptor *p;
int rc;
if(!my_session_handle)
@@ -486,12 +459,9 @@ Curl_gsk_secure_soc_close(gsk_handle * my_session_handle)
return rc;
}
-
-int
-Curl_gsk_environment_init(gsk_handle my_env_handle)
-
+int Curl_gsk_environment_init(gsk_handle my_env_handle)
{
- struct Curl_gsk_descriptor * p;
+ struct Curl_gsk_descriptor *p;
if(!my_env_handle)
return GSK_INVALID_HANDLE;
@@ -500,11 +470,9 @@ Curl_gsk_environment_init(gsk_handle my_env_handle)
}
-int
-Curl_gsk_secure_soc_init(gsk_handle my_session_handle)
-
+int Curl_gsk_secure_soc_init(gsk_handle my_session_handle)
{
- struct Curl_gsk_descriptor * p;
+ struct Curl_gsk_descriptor *p;
if(!my_session_handle)
return GSK_INVALID_HANDLE;
@@ -515,11 +483,10 @@ Curl_gsk_secure_soc_init(gsk_handle my_session_handle)
int
Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
- const char * buffer, int bufSize)
-
+ const char *buffer, int bufSize)
{
- struct Curl_gsk_descriptor * p;
- char * ebcdicbuf;
+ struct Curl_gsk_descriptor *p;
+ char *ebcdicbuf;
int rc;
if(!my_gsk_handle)
@@ -545,9 +512,8 @@ Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
int
Curl_gsk_attribute_set_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
GSK_ENUM_VALUE enumValue)
-
{
- struct Curl_gsk_descriptor * p;
+ struct Curl_gsk_descriptor *p;
if(!my_gsk_handle)
return GSK_INVALID_HANDLE;
@@ -559,9 +525,8 @@ Curl_gsk_attribute_set_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
int
Curl_gsk_attribute_set_numeric_value(gsk_handle my_gsk_handle,
GSK_NUM_ID numID, int numValue)
-
{
- struct Curl_gsk_descriptor * p;
+ struct Curl_gsk_descriptor *p;
if(!my_gsk_handle)
return GSK_INVALID_HANDLE;
@@ -573,10 +538,9 @@ Curl_gsk_attribute_set_numeric_value(gsk_handle my_gsk_handle,
int
Curl_gsk_attribute_set_callback(gsk_handle my_gsk_handle,
GSK_CALLBACK_ID callBackID,
- void * callBackAreaPtr)
-
+ void *callBackAreaPtr)
{
- struct Curl_gsk_descriptor * p;
+ struct Curl_gsk_descriptor *p;
if(!my_gsk_handle)
return GSK_INVALID_HANDLE;
@@ -586,13 +550,12 @@ Curl_gsk_attribute_set_callback(gsk_handle my_gsk_handle,
static int
-cachestring(struct Curl_gsk_descriptor * p,
- const char * ebcdicbuf, int bufsize, const char * * buffer)
-
+cachestring(struct Curl_gsk_descriptor *p,
+ const char *ebcdicbuf, int bufsize, const char **buffer)
{
int rc;
- char * asciibuf;
- struct gskstrlist * sp;
+ char *asciibuf;
+ struct gskstrlist *sp;
for(sp = p->strlist; sp; sp = sp->next)
if(sp->ebcdicstr == ebcdicbuf)
@@ -620,12 +583,11 @@ cachestring(struct Curl_gsk_descriptor * p,
int
Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
- const char * * buffer, int * bufSize)
-
+ const char **buffer, int *bufSize)
{
- struct Curl_gsk_descriptor * p;
+ struct Curl_gsk_descriptor *p;
int rc;
- const char * mybuf;
+ const char *mybuf;
int mylen;
if(!my_gsk_handle)
@@ -645,10 +607,9 @@ Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
int
Curl_gsk_attribute_get_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
- GSK_ENUM_VALUE * enumValue)
-
+ GSK_ENUM_VALUE *enumValue)
{
- struct Curl_gsk_descriptor * p;
+ struct Curl_gsk_descriptor *p;
if(!my_gsk_handle)
return GSK_INVALID_HANDLE;
@@ -659,10 +620,9 @@ Curl_gsk_attribute_get_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
int
Curl_gsk_attribute_get_numeric_value(gsk_handle my_gsk_handle,
- GSK_NUM_ID numID, int * numValue)
-
+ GSK_NUM_ID numID, int *numValue)
{
- struct Curl_gsk_descriptor * p;
+ struct Curl_gsk_descriptor *p;
if(!my_gsk_handle)
return GSK_INVALID_HANDLE;
@@ -674,11 +634,10 @@ Curl_gsk_attribute_get_numeric_value(gsk_handle my_gsk_handle,
int
Curl_gsk_attribute_get_cert_info(gsk_handle my_gsk_handle,
GSK_CERT_ID certID,
- const gsk_cert_data_elem * * certDataElem,
- int * certDataElementCount)
-
+ const gsk_cert_data_elem **certDataElem,
+ int *certDataElementCount)
{
- struct Curl_gsk_descriptor * p;
+ struct Curl_gsk_descriptor *p;
if(!my_gsk_handle)
return GSK_INVALID_HANDLE;
@@ -691,9 +650,8 @@ Curl_gsk_attribute_get_cert_info(gsk_handle my_gsk_handle,
int
Curl_gsk_secure_soc_misc(gsk_handle my_session_handle, GSK_MISC_ID miscID)
-
{
- struct Curl_gsk_descriptor * p;
+ struct Curl_gsk_descriptor *p;
if(!my_session_handle)
return GSK_INVALID_HANDLE;
@@ -703,11 +661,10 @@ Curl_gsk_secure_soc_misc(gsk_handle my_session_handle, GSK_MISC_ID miscID)
int
-Curl_gsk_secure_soc_read(gsk_handle my_session_handle, char * readBuffer,
- int readBufSize, int * amtRead)
-
+Curl_gsk_secure_soc_read(gsk_handle my_session_handle, char *readBuffer,
+ int readBufSize, int *amtRead)
{
- struct Curl_gsk_descriptor * p;
+ struct Curl_gsk_descriptor *p;
if(!my_session_handle)
return GSK_INVALID_HANDLE;
@@ -717,11 +674,10 @@ Curl_gsk_secure_soc_read(gsk_handle my_session_handle, char * readBuffer,
int
-Curl_gsk_secure_soc_write(gsk_handle my_session_handle, char * writeBuffer,
- int writeBufSize, int * amtWritten)
-
+Curl_gsk_secure_soc_write(gsk_handle my_session_handle, char *writeBuffer,
+ int writeBufSize, int *amtWritten)
{
- struct Curl_gsk_descriptor * p;
+ struct Curl_gsk_descriptor *p;
if(!my_session_handle)
return GSK_INVALID_HANDLE;
@@ -732,7 +688,6 @@ Curl_gsk_secure_soc_write(gsk_handle my_session_handle, char * writeBuffer,
const char *
Curl_gsk_strerror_a(int gsk_return_value)
-
{
return set_thread_string(LK_GSK_ERROR, gsk_strerror(gsk_return_value));
}
@@ -740,10 +695,9 @@ Curl_gsk_strerror_a(int gsk_return_value)
int
Curl_gsk_secure_soc_startInit(gsk_handle my_session_handle,
int IOCompletionPort,
- Qso_OverlappedIO_t * communicationsArea)
-
+ Qso_OverlappedIO_t *communicationsArea)
{
- struct Curl_gsk_descriptor * p;
+ struct Curl_gsk_descriptor *p;
if(!my_session_handle)
return GSK_INVALID_HANDLE;
@@ -753,15 +707,12 @@ Curl_gsk_secure_soc_startInit(gsk_handle my_session_handle,
#endif /* USE_GSKIT */
-
-
#ifdef HAVE_GSSAPI
/* ASCII wrappers for the GSSAPI procedures. */
static int
-Curl_gss_convert_in_place(OM_uint32 * minor_status, gss_buffer_t buf)
-
+Curl_gss_convert_in_place(OM_uint32 *minor_status, gss_buffer_t buf)
{
unsigned int i = buf->length;
@@ -789,9 +740,8 @@ Curl_gss_convert_in_place(OM_uint32 * minor_status, gss_buffer_t buf)
OM_uint32
-Curl_gss_import_name_a(OM_uint32 * minor_status, gss_buffer_t in_name,
- gss_OID in_name_type, gss_name_t * out_name)
-
+Curl_gss_import_name_a(OM_uint32 *minor_status, gss_buffer_t in_name,
+ gss_OID in_name_type, gss_name_t *out_name)
{
int rc;
unsigned int i;
@@ -818,17 +768,16 @@ Curl_gss_import_name_a(OM_uint32 * minor_status, gss_buffer_t in_name,
return rc;
}
-
OM_uint32
-Curl_gss_display_status_a(OM_uint32 * minor_status, OM_uint32 status_value,
- int status_type, gss_OID mech_type,
- gss_msg_ctx_t * message_context, gss_buffer_t status_string)
-
+Curl_gss_display_status_a(OM_uint32 *minor_status, OM_uint32 status_value,
+ int status_type, gss_OID mech_type,
+ gss_msg_ctx_t *message_context,
+ gss_buffer_t status_string)
{
int rc;
rc = gss_display_status(minor_status, status_value, status_type,
- mech_type, message_context, status_string);
+ mech_type, message_context, status_string);
if(rc != GSS_S_COMPLETE || !status_string ||
!status_string->length || !status_string->value)
@@ -844,19 +793,17 @@ Curl_gss_display_status_a(OM_uint32 * minor_status, OM_uint32 status_value,
return rc;
}
-
OM_uint32
-Curl_gss_init_sec_context_a(OM_uint32 * minor_status,
+Curl_gss_init_sec_context_a(OM_uint32 *minor_status,
gss_cred_id_t cred_handle,
- gss_ctx_id_t * context_handle,
+ gss_ctx_id_t *context_handle,
gss_name_t target_name, gss_OID mech_type,
gss_flags_t req_flags, OM_uint32 time_req,
gss_channel_bindings_t input_chan_bindings,
gss_buffer_t input_token,
- gss_OID * actual_mech_type,
- gss_buffer_t output_token, gss_flags_t * ret_flags,
- OM_uint32 * time_rec)
-
+ gss_OID *actual_mech_type,
+ gss_buffer_t output_token, gss_flags_t *ret_flags,
+ OM_uint32 *time_rec)
{
int rc;
gss_buffer_desc in;
@@ -885,13 +832,13 @@ Curl_gss_init_sec_context_a(OM_uint32 * minor_status,
}
rc = gss_init_sec_context(minor_status, cred_handle, context_handle,
- target_name, mech_type, req_flags, time_req,
- input_chan_bindings, inp, actual_mech_type,
- output_token, ret_flags, time_rec);
+ target_name, mech_type, req_flags, time_req,
+ input_chan_bindings, inp, actual_mech_type,
+ output_token, ret_flags, time_rec);
free(in.value);
if(rc != GSS_S_COMPLETE || !output_token ||
- !output_token->length || !output_token->value)
+ !output_token->length || !output_token->value)
return rc;
/* No way to allocate a buffer here, because it will be released by
@@ -906,17 +853,16 @@ Curl_gss_init_sec_context_a(OM_uint32 * minor_status,
OM_uint32
-Curl_gss_delete_sec_context_a(OM_uint32 * minor_status,
- gss_ctx_id_t * context_handle,
+Curl_gss_delete_sec_context_a(OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
gss_buffer_t output_token)
-
{
int rc;
rc = gss_delete_sec_context(minor_status, context_handle, output_token);
if(rc != GSS_S_COMPLETE || !output_token ||
- !output_token->length || !output_token->value)
+ !output_token->length || !output_token->value)
return rc;
/* No way to allocate a buffer here, because it will be released by
@@ -931,18 +877,16 @@ Curl_gss_delete_sec_context_a(OM_uint32 * minor_status,
#endif /* HAVE_GSSAPI */
-
#ifndef CURL_DISABLE_LDAP
/* ASCII wrappers for the LDAP procedures. */
void *
-Curl_ldap_init_a(char * host, int port)
-
+Curl_ldap_init_a(char *host, int port)
{
unsigned int i;
- char * ehost;
- void * result;
+ char *ehost;
+ void *result;
if(!host)
return (void *) ldap_init(host, port);
@@ -960,14 +904,12 @@ Curl_ldap_init_a(char * host, int port)
return result;
}
-
int
-Curl_ldap_simple_bind_s_a(void * ld, char * dn, char * passwd)
-
+Curl_ldap_simple_bind_s_a(void *ld, char *dn, char *passwd)
{
int i;
- char * edn;
- char * epasswd;
+ char *edn;
+ char *epasswd;
edn = (char *) NULL;
epasswd = (char *) NULL;
@@ -1002,22 +944,20 @@ Curl_ldap_simple_bind_s_a(void * ld, char * dn, char * passwd)
return i;
}
-
int
-Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
- char * * attrs, int attrsonly, LDAPMessage * * res)
-
+Curl_ldap_search_s_a(void *ld, char *base, int scope, char *filter,
+ char **attrs, int attrsonly, LDAPMessage **res)
{
int i;
int j;
- char * ebase;
- char * efilter;
- char * * eattrs;
+ char *ebase;
+ char *efilter;
+ char **eattrs;
int status;
ebase = (char *) NULL;
efilter = (char *) NULL;
- eattrs = (char * *) NULL;
+ eattrs = (char **) NULL;
status = LDAP_SUCCESS;
if(base) {
@@ -1063,9 +1003,9 @@ Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
QadrtConvertA2E(eattrs[j], attrs[j], i, i);
eattrs[j][i] = '\0';
- }
}
}
+ }
if(status == LDAP_SUCCESS)
status = ldap_search_s(ld, ebase? ebase: "", scope,
@@ -1077,7 +1017,7 @@ Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
free(eattrs[j]);
free(eattrs);
- }
+ }
free(efilter);
free(ebase);
@@ -1085,12 +1025,11 @@ Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
}
-struct berval * *
-Curl_ldap_get_values_len_a(void * ld, LDAPMessage * entry, const char * attr)
-
+struct berval **
+Curl_ldap_get_values_len_a(void *ld, LDAPMessage *entry, const char *attr)
{
- char * cp;
- struct berval * * result;
+ char *cp;
+ struct berval **result;
cp = (char *) NULL;
@@ -1101,7 +1040,7 @@ Curl_ldap_get_values_len_a(void * ld, LDAPMessage * entry, const char * attr)
if(!cp) {
ldap_set_lderrno(ld, LDAP_NO_MEMORY, NULL,
ldap_err2string(LDAP_NO_MEMORY));
- return (struct berval * *) NULL;
+ return (struct berval **) NULL;
}
QadrtConvertA2E(cp, attr, i, i);
@@ -1117,22 +1056,18 @@ Curl_ldap_get_values_len_a(void * ld, LDAPMessage * entry, const char * attr)
return result;
}
-
char *
Curl_ldap_err2string_a(int error)
-
{
return set_thread_string(LK_LDAP_ERROR, ldap_err2string(error));
}
-
char *
-Curl_ldap_get_dn_a(void * ld, LDAPMessage * entry)
-
+Curl_ldap_get_dn_a(void *ld, LDAPMessage *entry)
{
int i;
- char * cp;
- char * cp2;
+ char *cp;
+ char *cp2;
cp = ldap_get_dn(ld, entry);
@@ -1157,15 +1092,13 @@ Curl_ldap_get_dn_a(void * ld, LDAPMessage * entry)
return cp;
}
-
char *
-Curl_ldap_first_attribute_a(void * ld,
- LDAPMessage * entry, BerElement * * berptr)
-
+Curl_ldap_first_attribute_a(void *ld,
+ LDAPMessage *entry, BerElement **berptr)
{
int i;
- char * cp;
- char * cp2;
+ char *cp;
+ char *cp2;
cp = ldap_first_attribute(ld, entry, berptr);
@@ -1190,15 +1123,13 @@ Curl_ldap_first_attribute_a(void * ld,
return cp;
}
-
char *
-Curl_ldap_next_attribute_a(void * ld,
- LDAPMessage * entry, BerElement * berptr)
-
+Curl_ldap_next_attribute_a(void *ld,
+ LDAPMessage *entry, BerElement *berptr)
{
int i;
- char * cp;
- char * cp2;
+ char *cp;
+ char *cp2;
cp = ldap_next_attribute(ld, entry, berptr);
@@ -1225,7 +1156,6 @@ Curl_ldap_next_attribute_a(void * ld,
#endif /* CURL_DISABLE_LDAP */
-
static int
sockaddr2ebcdic(struct sockaddr_storage *dstaddr,
const struct sockaddr *srcaddr, int srclen)
@@ -1241,11 +1171,11 @@ sockaddr2ebcdic(struct sockaddr_storage *dstaddr,
sizeof(srcaddr->sa_family) || srclen > sizeof(*dstaddr)) {
errno = EINVAL;
return -1;
- }
+ }
memcpy((char *) dstaddr, (char *) srcaddr, srclen);
- switch (srcaddr->sa_family) {
+ switch(srcaddr->sa_family) {
case AF_UNIX:
srcu = (const struct sockaddr_un *) srcaddr;
@@ -1255,7 +1185,7 @@ sockaddr2ebcdic(struct sockaddr_storage *dstaddr,
i = QadrtConvertA2E(dstu->sun_path, srcu->sun_path, dstsize - 1, srclen);
dstu->sun_path[i] = '\0';
srclen = i + offsetof(struct sockaddr_un, sun_path);
- }
+ }
return srclen;
}
@@ -1278,13 +1208,13 @@ sockaddr2ascii(struct sockaddr *dstaddr, int dstlen,
if(!srcaddr || srclen < 0) {
errno = EINVAL;
return -1;
- }
+ }
memcpy((char *) dstaddr, (char *) srcaddr, srclen);
if(srclen >= offsetof(struct sockaddr_storage, ss_family) +
sizeof(srcaddr->ss_family)) {
- switch (srcaddr->ss_family) {
+ switch(srcaddr->ss_family) {
case AF_UNIX:
srcu = (const struct sockaddr_un *) srcaddr;
@@ -1303,9 +1233,8 @@ sockaddr2ascii(struct sockaddr *dstaddr, int dstlen,
return srclen;
}
-
int
-Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen)
+Curl_os400_connect(int sd, struct sockaddr *destaddr, int addrlen)
{
int i;
struct sockaddr_storage laddr;
@@ -1318,9 +1247,8 @@ Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen)
return connect(sd, (struct sockaddr *) &laddr, i);
}
-
int
-Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen)
+Curl_os400_bind(int sd, struct sockaddr *localaddr, int addrlen)
{
int i;
struct sockaddr_storage laddr;
@@ -1333,10 +1261,9 @@ Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen)
return bind(sd, (struct sockaddr *) &laddr, i);
}
-
int
-Curl_os400_sendto(int sd, char * buffer, int buflen, int flags,
- struct sockaddr * dstaddr, int addrlen)
+Curl_os400_sendto(int sd, char *buffer, int buflen, int flags,
+ struct sockaddr *dstaddr, int addrlen)
{
int i;
struct sockaddr_storage laddr;
@@ -1349,10 +1276,9 @@ Curl_os400_sendto(int sd, char * buffer, int buflen, int flags,
return sendto(sd, buffer, buflen, flags, (struct sockaddr *) &laddr, i);
}
-
int
-Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
- struct sockaddr * fromaddr, int * addrlen)
+Curl_os400_recvfrom(int sd, char *buffer, int buflen, int flags,
+ struct sockaddr *fromaddr, int *addrlen)
{
int rcvlen;
struct sockaddr_storage laddr;
@@ -1379,7 +1305,6 @@ Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
return rcvlen;
}
-
int
Curl_os400_getpeername(int sd, struct sockaddr *addr, int *addrlen)
{
@@ -1397,7 +1322,6 @@ Curl_os400_getpeername(int sd, struct sockaddr *addr, int *addrlen)
return retcode;
}
-
int
Curl_os400_getsockname(int sd, struct sockaddr *addr, int *addrlen)
{
@@ -1419,17 +1343,15 @@ Curl_os400_getsockname(int sd, struct sockaddr *addr, int *addrlen)
#ifdef HAVE_LIBZ
const char *
Curl_os400_zlibVersion(void)
-
{
return set_thread_string(LK_ZLIB_VERSION, zlibVersion());
}
int
-Curl_os400_inflateInit_(z_streamp strm, const char * version, int stream_size)
-
+Curl_os400_inflateInit_(z_streamp strm, const char *version, int stream_size)
{
- z_const char * msgb4 = strm->msg;
+ z_const char *msgb4 = strm->msg;
int ret;
ret = inflateInit(strm);
@@ -1440,13 +1362,11 @@ Curl_os400_inflateInit_(z_streamp strm, const char * version, int stream_size)
return ret;
}
-
int
Curl_os400_inflateInit2_(z_streamp strm, int windowBits,
- const char * version, int stream_size)
-
+ const char *version, int stream_size)
{
- z_const char * msgb4 = strm->msg;
+ z_const char *msgb4 = strm->msg;
int ret;
ret = inflateInit2(strm, windowBits);
@@ -1457,12 +1377,10 @@ Curl_os400_inflateInit2_(z_streamp strm, int windowBits,
return ret;
}
-
int
Curl_os400_inflate(z_streamp strm, int flush)
-
{
- z_const char * msgb4 = strm->msg;
+ z_const char *msgb4 = strm->msg;
int ret;
ret = inflate(strm, flush);
@@ -1473,12 +1391,10 @@ Curl_os400_inflate(z_streamp strm, int flush)
return ret;
}
-
int
Curl_os400_inflateEnd(z_streamp strm)
-
{
- z_const char * msgb4 = strm->msg;
+ z_const char *msgb4 = strm->msg;
int ret;
ret = inflateEnd(strm);
diff --git a/packages/OS400/os400sys.h b/packages/OS400/os400sys.h
index 8dafd6491..3b7667514 100644
--- a/packages/OS400/os400sys.h
+++ b/packages/OS400/os400sys.h
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/packages/Symbian/bwins/libcurlu.def b/packages/Symbian/bwins/libcurlu.def
deleted file mode 100644
index 7f30b7feb..000000000
--- a/packages/Symbian/bwins/libcurlu.def
+++ /dev/null
@@ -1,60 +0,0 @@
-EXPORTS
- curl_easy_cleanup @ 1 NONAME
- curl_easy_duphandle @ 2 NONAME
- curl_easy_escape @ 3 NONAME
- curl_easy_getinfo @ 4 NONAME
- curl_easy_init @ 5 NONAME
- curl_easy_pause @ 6 NONAME
- curl_easy_perform @ 7 NONAME
- curl_easy_reset @ 8 NONAME
- curl_easy_setopt @ 9 NONAME
- curl_easy_strerror @ 10 NONAME
- curl_easy_unescape @ 11 NONAME
- curl_escape @ 12 NONAME
- curl_formadd @ 13 NONAME
- curl_formfree @ 14 NONAME
- curl_formget @ 15 NONAME
- curl_free @ 16 NONAME
- curl_getdate @ 17 NONAME
- curl_getenv @ 18 NONAME
- curl_global_cleanup @ 19 NONAME
- curl_global_init @ 20 NONAME
- curl_global_init_mem @ 21 NONAME
- curl_maprintf @ 22 NONAME
- curl_mfprintf @ 23 NONAME
- curl_mprintf @ 24 NONAME
- curl_msnprintf @ 25 NONAME
- curl_msprintf @ 26 NONAME
- curl_multi_add_handle @ 27 NONAME
- curl_multi_assign @ 28 NONAME
- curl_multi_cleanup @ 29 NONAME
- curl_multi_fdset @ 30 NONAME
- curl_multi_info_read @ 31 NONAME
- curl_multi_init @ 32 NONAME
- curl_multi_perform @ 33 NONAME
- curl_multi_remove_handle @ 34 NONAME
- curl_multi_setopt @ 35 NONAME
- curl_multi_socket @ 36 NONAME
- curl_multi_socket_action @ 37 NONAME
- curl_multi_socket_all @ 38 NONAME
- curl_multi_strerror @ 39 NONAME
- curl_multi_timeout @ 40 NONAME
- curl_mvaprintf @ 41 NONAME
- curl_mvfprintf @ 42 NONAME
- curl_mvprintf @ 43 NONAME
- curl_mvsnprintf @ 44 NONAME
- curl_mvsprintf @ 45 NONAME
- curl_share_cleanup @ 46 NONAME
- curl_share_init @ 47 NONAME
- curl_share_setopt @ 48 NONAME
- curl_share_strerror @ 49 NONAME
- curl_slist_append @ 50 NONAME
- curl_slist_free_all @ 51 NONAME
- curl_strequal @ 52 NONAME
- curl_strnequal @ 53 NONAME
- curl_unescape @ 54 NONAME
- curl_version @ 55 NONAME
- curl_version_info @ 56 NONAME
- curl_easy_recv @ 57 NONAME
- curl_easy_send @ 58 NONAME
- curl_multi_wait @ 59 NONAME
diff --git a/packages/Symbian/eabi/libcurlu.def b/packages/Symbian/eabi/libcurlu.def
deleted file mode 100644
index 7f30b7feb..000000000
--- a/packages/Symbian/eabi/libcurlu.def
+++ /dev/null
@@ -1,60 +0,0 @@
-EXPORTS
- curl_easy_cleanup @ 1 NONAME
- curl_easy_duphandle @ 2 NONAME
- curl_easy_escape @ 3 NONAME
- curl_easy_getinfo @ 4 NONAME
- curl_easy_init @ 5 NONAME
- curl_easy_pause @ 6 NONAME
- curl_easy_perform @ 7 NONAME
- curl_easy_reset @ 8 NONAME
- curl_easy_setopt @ 9 NONAME
- curl_easy_strerror @ 10 NONAME
- curl_easy_unescape @ 11 NONAME
- curl_escape @ 12 NONAME
- curl_formadd @ 13 NONAME
- curl_formfree @ 14 NONAME
- curl_formget @ 15 NONAME
- curl_free @ 16 NONAME
- curl_getdate @ 17 NONAME
- curl_getenv @ 18 NONAME
- curl_global_cleanup @ 19 NONAME
- curl_global_init @ 20 NONAME
- curl_global_init_mem @ 21 NONAME
- curl_maprintf @ 22 NONAME
- curl_mfprintf @ 23 NONAME
- curl_mprintf @ 24 NONAME
- curl_msnprintf @ 25 NONAME
- curl_msprintf @ 26 NONAME
- curl_multi_add_handle @ 27 NONAME
- curl_multi_assign @ 28 NONAME
- curl_multi_cleanup @ 29 NONAME
- curl_multi_fdset @ 30 NONAME
- curl_multi_info_read @ 31 NONAME
- curl_multi_init @ 32 NONAME
- curl_multi_perform @ 33 NONAME
- curl_multi_remove_handle @ 34 NONAME
- curl_multi_setopt @ 35 NONAME
- curl_multi_socket @ 36 NONAME
- curl_multi_socket_action @ 37 NONAME
- curl_multi_socket_all @ 38 NONAME
- curl_multi_strerror @ 39 NONAME
- curl_multi_timeout @ 40 NONAME
- curl_mvaprintf @ 41 NONAME
- curl_mvfprintf @ 42 NONAME
- curl_mvprintf @ 43 NONAME
- curl_mvsnprintf @ 44 NONAME
- curl_mvsprintf @ 45 NONAME
- curl_share_cleanup @ 46 NONAME
- curl_share_init @ 47 NONAME
- curl_share_setopt @ 48 NONAME
- curl_share_strerror @ 49 NONAME
- curl_slist_append @ 50 NONAME
- curl_slist_free_all @ 51 NONAME
- curl_strequal @ 52 NONAME
- curl_strnequal @ 53 NONAME
- curl_unescape @ 54 NONAME
- curl_version @ 55 NONAME
- curl_version_info @ 56 NONAME
- curl_easy_recv @ 57 NONAME
- curl_easy_send @ 58 NONAME
- curl_multi_wait @ 59 NONAME
diff --git a/packages/Symbian/group/bld.inf b/packages/Symbian/group/bld.inf
deleted file mode 100644
index 354a84382..000000000
--- a/packages/Symbian/group/bld.inf
+++ /dev/null
@@ -1,10 +0,0 @@
-//
-// libcurl and curl bld.inf file for Symbian OS
-//
-PRJ_EXPORTS
- libcurl.iby /epoc32/rom/include/libcurl.iby
- curl.iby /epoc32/rom/include/curl.iby
-
-PRJ_MMPFILES
- libcurl.mmp
- curl.mmp
diff --git a/packages/Symbian/group/curl.iby b/packages/Symbian/group/curl.iby
deleted file mode 100644
index 7921aaa07..000000000
--- a/packages/Symbian/group/curl.iby
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// curl file transfer utility command-line utility
-//
-// Use this file with buildrom to add curl to a device ROM
-//
-
-#ifndef CURL_IBY
-#define CURL_IBY
-
-#include <openenv.iby>
-#include <libcurl.iby>
-
-file=ABI_DIR\BUILD_DIR\curl.exe \sys\bin\curl.exe
-
-#endif // CURL_IBY
diff --git a/packages/Symbian/group/curl.mmp b/packages/Symbian/group/curl.mmp
deleted file mode 100644
index af12d8b1f..000000000
--- a/packages/Symbian/group/curl.mmp
+++ /dev/null
@@ -1,64 +0,0 @@
-//
-// curl network retrieval client
-//
-
-TARGET curl.exe
-TARGETTYPE exe
-UID 0x00000000 0xF0206442
-
-SOURCEPATH ../../../src
-SOURCE \
- tool_binmode.c \
- tool_bname.c \
- tool_cb_dbg.c \
- tool_cb_hdr.c \
- tool_cb_prg.c \
- tool_cb_rea.c \
- tool_cb_see.c \
- tool_cb_wrt.c \
- tool_cfgable.c \
- tool_convert.c \
- tool_dirhie.c \
- tool_doswin.c \
- tool_easysrc.c \
- tool_formparse.c \
- tool_getparam.c \
- tool_getpass.c \
- tool_help.c \
- tool_helpers.c \
- tool_homedir.c \
- tool_hugehelp.c \
- tool_libinfo.c \
- tool_main.c \
- tool_metalink.c \
- tool_mfiles.c \
- tool_msgs.c \
- tool_operate.c \
- tool_operhlp.c \
- tool_panykey.c \
- tool_paramhlp.c \
- tool_parsecfg.c \
- tool_setopt.c \
- tool_sleep.c \
- tool_urlglob.c \
- tool_util.c \
- tool_vms.c \
- tool_writeenv.c \
- tool_writeout.c \
- tool_writeout_json.c \
- tool_xattr.c
-
-SOURCEPATH ../../../lib
-SOURCE \
- strcase.c nonblock.c
-
-USERINCLUDE ../../../src ../../../lib ../../../include/gnurl
-
-SYSTEMINCLUDE ../../../include /epoc32/include /epoc32/include/stdapis
-
-LIBRARY euser.lib libc.lib libcurl.lib
-STATICLIBRARY libcrt0.lib
-
-CAPABILITY NetworkServices
-
-EPOCSTACKSIZE 0x8000
diff --git a/packages/Symbian/group/curl.pkg b/packages/Symbian/group/curl.pkg
deleted file mode 100644
index 17c64f1e0..000000000
--- a/packages/Symbian/group/curl.pkg
+++ /dev/null
@@ -1,26 +0,0 @@
-; curl package definition file
-; Use with makesis to create a Symbian .sis package
-
-;Language - standard language definitions
-&EN
-
-;Header - standard sis file header including version number
-;Version scheme: curl's major, curl's minor, curl's subminor*100 + build number
-; e.g. The third Symbian package of curl ver. 7.20.1 would have a SIS package
-; version of 7, 20, 103
-#{"curl"}, (0xF0206442), 7, 20, <please_update_version>, TYPE=SA
-
-; Vendor name
-%{"curl project"}
-:"curl project"
-
-; Embedded component
-@"libcurl.sis",(0xF0206D00)
-
-; A dependency on P.I.P.S. and the stdio server are probably good to have here
-;(0x20009A80), *, *, *, {"Open C Standard Libraries"}
-;(0x20009A81), *, *, *, {"P.I.P.S. for UIQ 3"}
-;(0x20009AA2), *, *, *, {"Symbian OS STDIOSERVER"}
-
-;Files - standard file specifications
-"\epoc32\release\armv5\urel\curl.exe" - "$:\sys\bin\curl.exe"
diff --git a/packages/Symbian/group/libcurl.iby b/packages/Symbian/group/libcurl.iby
deleted file mode 100644
index 373f5b37d..000000000
--- a/packages/Symbian/group/libcurl.iby
+++ /dev/null
@@ -1,14 +0,0 @@
-//
-// libcurl file transfer DLL
-//
-// Use this file with buildrom to add libcurl to a device ROM
-//
-
-#ifndef LIBCURL_IBY
-#define LIBCURL_IBY
-
-#include <openenv.iby>
-
-file=ABI_DIR\BUILD_DIR\libcurl.dll \sys\bin\libcurl.dll
-
-#endif // LIBCURL_IBY
diff --git a/packages/Symbian/group/libcurl.mmp b/packages/Symbian/group/libcurl.mmp
deleted file mode 100644
index c52056afb..000000000
--- a/packages/Symbian/group/libcurl.mmp
+++ /dev/null
@@ -1,67 +0,0 @@
-//
-// libcurl.dll curl network retrieval client library
-//
-
-// Build-time options (uncomment these to enable)
-#define ENABLE_ZLIB // Enable gzip/deflate decompression
-//#define ENABLE_SSL // Enable SSL for HTTPS/FTPS (requires S60 Open C SDK)
-
-TARGET libcurl.dll
-TARGETTYPE dll
-UID 0x1000008d 0xF0206D00
-
-MACRO BUILDING_LIBCURL
-
-#ifdef ENABLE_ZLIB
-MACRO HAVE_LIBZ
-#endif
-#ifdef ENABLE_SSL
-MACRO USE_OPENSSL
-#endif
-
-SOURCEPATH ../../../lib
-SOURCE \
- file.c timeval.c base64.c hostip.c progress.c formdata.c \
- cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c \
- ldap.c vtls/openssl.c version.c getenv.c escape.c mprintf.c telnet.c \
- netrc.c getinfo.c transfer.c strequal.c easy.c security.c krb4.c \
- curl_fnmatch.c fileinfo.c ftplistparser.c wildcard.c krb5.c \
- memdebug.c http_chunks.c strtok.c connect.c llist.c hash.c multi.c \
- content_encoding.c share.c http_digest.c md4.c md5.c curl_rand.c \
- http_negotiate.c inet_pton.c strtoofft.c strerror.c amigaos.c \
- hostasyn.c hostip4.c hostip6.c hostsyn.c inet_ntop.c parsedate.c \
- select.c vtls/gtls.c vtls/vtls.c tftp.c splay.c strdup.c socks.c \
- ssh.c vtls/nss.c strcase.c curl_addrinfo.c socks_gssapi.c \
- socks_sspi.c curl_sspi.c slist.c nonblock.c curl_memrchr.c imap.c \
- pop3.c smtp.c pingpong.c rtsp.c curl_threads.c warnless.c hmac.c \
- curl_rtmp.c openldap.c curl_gethostname.c gopher.c \
- idn_win32.c vtls/cyassl.c http_proxy.c non-ascii.c \
- asyn-ares.c asyn-thread.c curl_gssapi.c http_ntlm.c curl_ntlm_wb.c \
- curl_ntlm_core.c curl_sasl.c vtls/schannel.c curl_multibyte.c \
- conncache.c curl_sasl_sspi.c smb.c curl_endian.c \
- curl_des.c curl_range.c system_win32.c sha256.c \
- vauth/vauth.c vauth/cleartext.c vauth/cram.c vauth/digest.c \
- vauth/digest_sspi.c vauth/krb5_gssapi.c vauth/krb5_sspi.c \
- vauth/ntlm.c vauth/ntlm_sspi.c vauth/oauth2.c vauth/spnego_gssapi.c \
- vauth/spnego_sspi.c
-
-USERINCLUDE ../../../lib ../../../include/gnurl
-#ifdef ENABLE_SSL
-SYSTEMINCLUDE /epoc32/include/osextensions/stdapis
-// Older versions of the SDK need this instead:
-//USERINCLUDE /epoc32/include/stdapis/openssl
-#endif
-
-SYSTEMINCLUDE ../../../include /epoc32/include/stdapis /epoc32/include
-
-LIBRARY euser.lib libc.lib
-#ifdef ENABLE_ZLIB
-LIBRARY ezlib.lib
-#endif
-#ifdef ENABLE_SSL
-LIBRARY libssl.lib libcrypto.lib
-#endif
-
-CAPABILITY NetworkServices
-
-EPOCALLOWDLLDATA
diff --git a/packages/Symbian/group/libcurl.pkg b/packages/Symbian/group/libcurl.pkg
deleted file mode 100644
index 6b0479753..000000000
--- a/packages/Symbian/group/libcurl.pkg
+++ /dev/null
@@ -1,22 +0,0 @@
-; libcurl package definition file
-; Use with makesis to create a Symbian .sis package
-
-;Language - standard language definitions
-&EN
-
-;Header - standard sis file header including version number
-;Version scheme: curl's major, curl's minor, curl's subminor*100 + build number
-; e.g. The third Symbian package of curl ver. 7.20.1 would have a SIS package
-; version of 7, 20, 103
-#{"libcurl"}, (0xF0206D00), 7, 20, <please_update_version>, TYPE=SA
-
-; Vendor name
-%{"curl project"}
-:"curl project"
-
-; A dependency on P.I.P.S. is probably a good idea to add here
-;(0x20009A80), *, *, *, {"Open C Standard Libraries"}
-;(0x20009A81), *, *, *, {"P.I.P.S. for UIQ 3"}
-
-;Files - standard file specifications
-"\epoc32\release\armv5\urel\libcurl.dll" - "$:\sys\bin\libcurl.dll"
diff --git a/packages/Symbian/readme.txt b/packages/Symbian/readme.txt
deleted file mode 100644
index d6312fbe3..000000000
--- a/packages/Symbian/readme.txt
+++ /dev/null
@@ -1,93 +0,0 @@
-Curl on Symbian OS
-==================
-This is a basic port of curl and libcurl to Symbian OS. The port is
-a straightforward one using Symbian's P.I.P.S. POSIX compatibility
-layer, which was first available for OS version 9.1. A more complete
-port would involve writing a Symbian C++ binding, or wrapping libcurl
-as a Symbian application server with a C++ API to handle requests
-from client applications as well as creating a GUI application to allow
-file transfers. The author has no current plans to do so.
-
-This means that integration with standard Symbian OS programs can be
-tricky, since libcurl isn't designed with Symbian's native asynchronous
-message passing idioms in mind. However, it may be possible to use libcurl
-in an active object-based application through libcurl's multi interface.
-The port is most easily used when porting POSIX applications to Symbian
-OS using P.I.P.S. (a.k.a. Open C).
-
-libcurl is built as a standard Symbian ordinal-linked DLL, and curl is
-built as a text mode EXE application. They have not been Symbian
-Signed, which is required in order to install them on most phones.
-
-Following are some things to keep in mind when using this port.
-
-
-curl notes
-----------
-When starting curl in the Windows emulator from the Windows command-line,
-place a double-dash -- before the first curl command-line option.
-e.g. \epoc32\release\winscw\udeb\curl -- -v http://localhost/
-Failure to do so may mean that some of your options won't be correctly
-processed.
-
-Symbian's ESHELL allows for redirecting stdin and stdout to files, but
-stderr goes to the epocwind.out file (on the emulator). The standard
-curl options -o, --stderr and --trace-ascii can be used to
-redirect output to a file (or stdout) instead.
-
-P.I.P.S. doesn't inherit the current working directory at startup from
-the shell, so relative path names are always relative to
-C:\Private\f0206442\.
-
-P.I.P.S. provides no way to disable echoing of characters as they are
-entered, so passwords typed in on the console will be visible. It also
-line buffers keyboard input so interactive telnet sessions are not very
-feasible.
-
-All screen output disappears after curl exits, so after a command completes,
-curl waits by default for Enter to be pressed before exiting. This behaviour
-is suppressed when the -s option is given.
-
-curl's "home directory" in Symbian is C:\Private\f0206442\. The .curlrc file
-is read from this directory on startup.
-
-
-libcurl notes
--------------
-libcurl uses writable static data, so the EPOCALLOWDLLDATA option is
-used in its MMP file, with the corresponding additional memory usage
-and limitations on the Windows emulator.
-
-curl_global_init() *must* be called (either explicitly or implicitly through
-calling certain other libcurl functions) before any libcurl functions
-that could allocate memory (like curl_getenv()).
-
-P.I.P.S. doesn't support signals or the alarm() call, so some timeouts
-(such as the connect timeout) are not honoured. This should not be
-an issue once support for CURLRES_THREADED is added for Symbian.
-
-P.I.P.S. causes a USER:87 panic if certain timeouts much longer than
-half an hour are selected.
-
-LDAP, SCP or SFTP methods are not supported due to lack of support for
-the dependent libraries on Symbian.
-
-gzip and deflate decompression is supported when the appropriate macro
-is uncommented in the libcurl.mmp file.
-
-SSL/TLS encryption is not enabled by default, but it is possible to add
-when the OpenSSL libraries included in the S60 Open C SDK are available.
-The appropriate macro in the libcurl.mmp file must be uncommented to
-enable support.
-
-NTLM authentication may not work on some servers due to the lack of
-MD4 support in the OpenSSL libraries included with Open C.
-
-Debug builds are not supported (i.e. --enable-debug) because they cause
-additional symbol exports in the library which are not frozen in the .def
-files.
-
-
-Dan Fandrich
-dan@coneharvesters.com
-March 2010
diff --git a/packages/TPF/curl.mak b/packages/TPF/curl.mak
index d8d55a805..5d6f3d717 100644
--- a/packages/TPF/curl.mak
+++ b/packages/TPF/curl.mak
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/packages/TPF/maketpf.env_curl b/packages/TPF/maketpf.env_curl
index fc6e46fca..662cc7c4d 100644
--- a/packages/TPF/maketpf.env_curl
+++ b/packages/TPF/maketpf.env_curl
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/packages/TPF/maketpf.env_curllib b/packages/TPF/maketpf.env_curllib
index 45c68d739..160f401f7 100644
--- a/packages/TPF/maketpf.env_curllib
+++ b/packages/TPF/maketpf.env_curllib
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/packages/vms/Makefile.am b/packages/vms/Makefile.am
index f5cf9a93f..16db59554 100644
--- a/packages/vms/Makefile.am
+++ b/packages/vms/Makefile.am
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/packages/vms/curl_crtl_init.c b/packages/vms/curl_crtl_init.c
index b8e5f7f50..63c674275 100644
--- a/packages/vms/curl_crtl_init.c
+++ b/packages/vms/curl_crtl_init.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/packages/vms/curl_gnv_build_steps.txt b/packages/vms/curl_gnv_build_steps.txt
index 52dc32881..2c3dba1da 100644
--- a/packages/vms/curl_gnv_build_steps.txt
+++ b/packages/vms/curl_gnv_build_steps.txt
@@ -36,7 +36,7 @@ time that this document was written.
[gnv.common_src]curl_*_original_src.bck is the original source of the curl kit
as provided by the curl project. [gnv.vms_src]curl-*_vms_src.bck, if present,
has the OpenVMS specific files that are used for building that are not yet in
-the curl source kits for that release distributed https://curl.haxx.se
+the curl source kits for that release distributed https://curl.se
These backup savesets should be restored to different directory trees on
an ODS-5 volume(s) which are referenced by concealed rooted logical names.
diff --git a/packages/vms/curlmsg.h b/packages/vms/curlmsg.h
index 55c9ee5cb..b3d0b252b 100644
--- a/packages/vms/curlmsg.h
+++ b/packages/vms/curlmsg.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/packages/vms/curlmsg.msg b/packages/vms/curlmsg.msg
index 73bc763e8..e86aee7c3 100644
--- a/packages/vms/curlmsg.msg
+++ b/packages/vms/curlmsg.msg
@@ -9,7 +9,7 @@
!
! This software is licensed as described in the file COPYING, which
! you should have received as part of this distribution. The terms
-! are also available at https://curl.haxx.se/docs/copyright.html.
+! are also available at https://curl.se/docs/copyright.html.
!
! You may opt to use, copy, modify, merge, publish, distribute and/or sell
! copies of the Software, and permit persons to whom the Software is
diff --git a/packages/vms/curlmsg_vms.h b/packages/vms/curlmsg_vms.h
index 9dbc6ab71..3392a4cc4 100644
--- a/packages/vms/curlmsg_vms.h
+++ b/packages/vms/curlmsg_vms.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/plan9/include/mkfile b/plan9/include/mkfile
index c1ed850fa..cbf403f89 100644
--- a/plan9/include/mkfile
+++ b/plan9/include/mkfile
@@ -5,11 +5,11 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/plan9/lib/mkfile b/plan9/lib/mkfile
index d7a7ac5e2..d64b465c0 100644
--- a/plan9/lib/mkfile
+++ b/plan9/lib/mkfile
@@ -5,11 +5,11 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/plan9/lib/mkfile.inc b/plan9/lib/mkfile.inc
index 0966d773e..b202f57e3 100755
--- a/plan9/lib/mkfile.inc
+++ b/plan9/lib/mkfile.inc
@@ -6,11 +6,11 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/plan9/mkfile b/plan9/mkfile
index a9b4fe6da..0fd18f493 100644
--- a/plan9/mkfile
+++ b/plan9/mkfile
@@ -5,11 +5,11 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/plan9/mkfile.proto b/plan9/mkfile.proto
index edb79f50d..a88374cda 100644
--- a/plan9/mkfile.proto
+++ b/plan9/mkfile.proto
@@ -5,11 +5,11 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/plan9/src/mkfile b/plan9/src/mkfile
index 889d06686..f75207890 100644
--- a/plan9/src/mkfile
+++ b/plan9/src/mkfile
@@ -5,11 +5,11 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/plan9/src/mkfile.inc b/plan9/src/mkfile.inc
index 0966d773e..b202f57e3 100755
--- a/plan9/src/mkfile.inc
+++ b/plan9/src/mkfile.inc
@@ -6,11 +6,11 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index 3b39796ae..8664c4fff 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/scripts/completion.pl b/scripts/completion.pl
index c717c6d43..8bbf4838a 100755
--- a/scripts/completion.pl
+++ b/scripts/completion.pl
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -37,7 +37,7 @@ Getopt::Long::GetOptions(
Pod::Usage::pod2usage() if $help;
my $regex = '\s+(?:(-[^\s]+),\s)?(--[^\s]+)\s*(\<.+?\>)?\s+(.*)';
-my @opts = parse_main_opts('--help', $regex);
+my @opts = parse_main_opts('--help all', $regex);
if ($shell eq 'fish') {
print "# curl fish completion\n\n";
diff --git a/scripts/contributors.sh b/scripts/contributors.sh
index 6a6d34484..6f3cf6af2 100755
--- a/scripts/contributors.sh
+++ b/scripts/contributors.sh
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -34,7 +34,7 @@ if test "$start" = "-h"; then
exit
fi
if test -z "$start"; then
- start=`git tag --sort=taggerdate | tail -1`;
+ start=`git tag --sort=taggerdate | grep "^curl-" | tail -1`;
echo "Since $start:"
fi
diff --git a/scripts/contrithanks.sh b/scripts/contrithanks.sh
index 641259216..36d289ddb 100755
--- a/scripts/contrithanks.sh
+++ b/scripts/contrithanks.sh
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -33,7 +33,7 @@ if test "$start" = "-h"; then
exit
fi
if test -z "$start"; then
- start=`git tag --sort=taggerdate | tail -1`;
+ start=`git tag --sort=taggerdate | grep "^curl-" | tail -1`;
fi
@@ -64,7 +64,7 @@ sed -e 's/^ //' -e 's/ $//g' -e 's/@users.noreply.github.com$/ on github/'
# grep out the list of names from RELEASE-NOTES
# split on ", "
-# remove leading white spaces
+# remove leading whitespace
grep -a "^ [^ (]" RELEASE-NOTES| \
sed 's/, */\n/g'| \
sed 's/^ *//'
diff --git a/scripts/copyright.pl b/scripts/copyright.pl
index 5649cad4f..d1f8ef7ec 100755
--- a/scripts/copyright.pl
+++ b/scripts/copyright.pl
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -44,11 +44,11 @@ my @skiplist=(
'^projects/Windows/.*.vcxproj.filters$', # generated MSVC file
'^m4/ax_compile_check_sizeof.m4$', # imported, leave be
'^.mailmap', # git control file
- '^winbuild/BUILD.WINDOWS.txt$', # instructions
'\/readme',
'^.github/', # github instruction files
'^.dcignore', # deepcode.ai instruction file
'^.muse/', # muse-CI control files
+ "buildconf", # its nothing to copyright
# docs/ files we're okay with without copyright
'INSTALL.cmake',
@@ -63,17 +63,6 @@ my @skiplist=(
'^lib\/libcurl.plist',
'^lib\/libcurl.vers.in',
- # symbian build files we know little about
- '^packages\/Symbian\/bwins\/libcurlu.def',
- '^packages\/Symbian\/eabi\/libcurlu.def',
- '^packages\/Symbian\/group\/bld.inf',
- '^packages\/Symbian\/group\/curl.iby',
- '^packages\/Symbian\/group\/curl.mmp',
- '^packages\/Symbian\/group\/curl.pkg',
- '^packages\/Symbian\/group\/libcurl.iby',
- '^packages\/Symbian\/group\/libcurl.mmp',
- '^packages\/Symbian\/group\/libcurl.pkg',
-
# vms files
'^packages\/vms\/build_vms.com',
'^packages\/vms\/curl_release_note_start.txt',
diff --git a/scripts/coverage.sh b/scripts/coverage.sh
index cae5e028f..e2b65b7f0 100755
--- a/scripts/coverage.sh
+++ b/scripts/coverage.sh
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/scripts/delta b/scripts/delta
index 28642aab0..72c3fa0eb 100755
--- a/scripts/delta
+++ b/scripts/delta
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -35,7 +35,7 @@ if($start eq "-h") {
exit;
}
elsif($start eq "") {
- $start = `git tag --sort=taggerdate | tail -1`;
+ $start = `git tag --sort=taggerdate | grep "^curl-" | tail -1`;
chomp $start;
}
@@ -83,6 +83,9 @@ $apublic=`git grep ^CURL_EXTERN -- include/curl | wc -l`;
$bpublic=`git grep ^CURL_EXTERN $start -- include/curl | wc -l`;
$public = $apublic - $bpublic;
+# diffstat
+$diffstat=`git diff --stat $start.. | tail -1`;
+
# Changes/bug-fixes currently logged
open(F, "<RELEASE-NOTES");
while(<F>) {
@@ -115,27 +118,23 @@ close(F);
########################################################################
# Produce the summary
-print "== Since $start ==\n";
-printf "Commits: %d (out of %d)\n",
+print "== Since $start $taggednice ==\n";
+printf "Elapsed time: %.1f days\n",
+ $elapsed / 3600 / 24;
+printf "Commits: %d (out of %d)\n",
$commits, $acommits;
-printf "Commit authors: %d out of which %d are new (out of %d)\n",
+printf "Commit authors: %d, %d new (total %d)\n",
$committers, $ncommitters, $acommitters;
-printf "Contributors in RELEASE-NOTES: %d\n",
- $numcontributors;
-printf "New contributors: %d (out of %d)\n",
- $contribs, $acontribs;
-printf "New curl_easy_setopt() options: %d (out of %d)\n",
+printf "Contributors: %d, %d new (total %d)\n",
+ $numcontributors, $contribs, $acontribs;
+printf "New public functions: %d (total %d)\n",
+ $public, $apublic;
+printf "New curl_easy_setopt() options: %d (total %d)\n",
$nsetopts, $asetopts;
-printf "New command line options: %d (out of %d)\n",
+printf "New command line options: %d (total %d)\n",
$noptions, $aoptions;
-
+printf "Changes logged: %d\n", $numchanges;
+printf "Bugfixes logged: %d\n", $numbugfixes;
printf "Deleted %d files, added %d files (total %d)\n",
$deletes, $creates, $afiles;
-
-printf "Elapsed time: %.1f days (since$taggednice)\n",
- $elapsed / 3600 / 24;
-printf "Changes logged: %d\n", $numchanges;
-printf "Bugfixes logged: %d\n", $numbugfixes;
-
-printf "New public functions: %d (out of %d)\n",
- $public, $apublic;
+print "Diffstat:$diffstat";
diff --git a/scripts/installcheck.sh b/scripts/installcheck.sh
index bc3e6c208..6d397a42a 100644
--- a/scripts/installcheck.sh
+++ b/scripts/installcheck.sh
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/scripts/log2changes.pl b/scripts/log2changes.pl
index ec470c967..69cbfd4f3 100755
--- a/scripts/log2changes.pl
+++ b/scripts/log2changes.pl
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/scripts/release-notes.pl b/scripts/release-notes.pl
index d26c045a2..1aea3b52a 100755
--- a/scripts/release-notes.pl
+++ b/scripts/release-notes.pl
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -137,8 +137,8 @@ sub onecommit {
$ref = $closes[0];
}
- if($ref =~ /^(\d+)/) {
- $ref = "https://curl.haxx.se/bug/?i=$1"
+ if($ref =~ /^#?(\d+)/) {
+ $ref = "https://curl.se/bug/?i=$1"
}
if($ref) {
my $r = getref();
@@ -156,7 +156,8 @@ for my $l (@releasenotes) {
push @o, $l;
push @o, "\n";
for my $f (@line) {
- push @o, sprintf " o $f%s\n", $moreinfo{$f}? sprintf(" [%d]", $moreinfo{$f}): "";
+ push @o, sprintf " o %s%s\n", $f,
+ $moreinfo{$f}? sprintf(" [%d]", $moreinfo{$f}): "";
$refused[$moreinfo{$f}]=3;
}
push @o, " --- new entries are listed above this ---";
@@ -208,6 +209,6 @@ exit;
# Debug: show unused references
for my $r (1 .. $#refs) {
if($refused[$r] != 3) {
- printf "$r is %d!\n", $refused[$r];
+ printf "%s is %d!\n", $r, $refused[$r];
}
}
diff --git a/scripts/singleuse.pl b/scripts/singleuse.pl
index ce77fdf05..e4b5a127e 100755
--- a/scripts/singleuse.pl
+++ b/scripts/singleuse.pl
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/scripts/travis/before_script.sh b/scripts/travis/before_script.sh
index 92f5cb233..ffa5e209a 100755
--- a/scripts/travis/before_script.sh
+++ b/scripts/travis/before_script.sh
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/scripts/travis/iconv-env.sh b/scripts/travis/iconv-env.sh
index 129eb10a9..bf4b87662 100755
--- a/scripts/travis/iconv-env.sh
+++ b/scripts/travis/iconv-env.sh
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/scripts/travis/script.sh b/scripts/travis/script.sh
index 7f9e56adc..49d45b700 100755
--- a/scripts/travis/script.sh
+++ b/scripts/travis/script.sh
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -49,7 +49,7 @@ if [ "$T" = "debug" ]; then
make
make examples
if [ -z $NOTESTS ]; then
- make TFLAGS=-n test-nonflaky
+ make test-nonflaky
fi
fi
@@ -106,6 +106,7 @@ fi
if [ "$T" = "cmake" ]; then
cmake -H. -Bbuild -DCURL_WERROR=ON $C
cmake --build build
+ env TFLAGS="!1139" cmake --build build --target test-nonflaky
fi
if [ "$T" = "distcheck" ]; then
diff --git a/scripts/updatemanpages.pl b/scripts/updatemanpages.pl
index 21a7df174..2b6e25a65 100755
--- a/scripts/updatemanpages.pl
+++ b/scripts/updatemanpages.pl
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 2f4f2c5b1..d2faa8fe1 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -78,6 +78,12 @@ if(CURL_HAS_LTO)
INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE)
endif()
+if(ENABLE_UNICODE AND MINGW)
+ target_link_libraries(${EXE_NAME} -municode)
+ # GCC doesn't know about wmain
+ set_source_files_properties(tool_main.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes -Wno-missing-declarations")
+endif()
+
source_group("curlX source files" FILES ${GNURLX_CFILES})
source_group("curl source files" FILES ${GNURL_CFILES})
source_group("curl header files" FILES ${GNURL_HFILES})
diff --git a/src/Makefile.Watcom b/src/Makefile.Watcom
deleted file mode 100644
index 795fd5b1a..000000000
--- a/src/Makefile.Watcom
+++ /dev/null
@@ -1,234 +0,0 @@
-#***************************************************************************
-# _ _ ____ _
-# Project ___| | | | _ \| |
-# / __| | | | |_) | |
-# | (__| |_| | _ <| |___
-# \___|\___/|_| \_\_____|
-#
-# Copyright (C) 2005 - 2008, Gisle Vanem <gvanem@yahoo.no>.
-# Copyright (C) 2005 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
-#
-# This software is licensed as described in the file COPYING, which
-# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
-#
-# You may opt to use, copy, modify, merge, publish, distribute and/or sell
-# copies of the Software, and permit persons to whom the Software is
-# furnished to do so, under the terms of the COPYING file.
-#
-# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
-# KIND, either express or implied.
-#
-#***************************************************************************
-
-#
-# Watcom / OpenWatcom / Win32 makefile for curl.
-#
-
-.ERASE
-
-!if $(__VERSION__) < 1280
-!message !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-!message ! This Open Watcom version is too old and is no longer supported !
-!message ! Please download latest version from www.openwatcom.org !
-!message !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-!error Unsupported version of Open Watcom
-!endif
-
-!ifndef %watcom
-!error WATCOM environment variable not set!
-!endif
-
-# In order to process Makefile.inc wmake must be called with -u switch!
-!ifndef %MAKEFLAGS
-!error You MUST call wmake with the -u switch!
-!endif
-
-!ifdef %libname
-LIBNAME = $(%libname)
-!else
-LIBNAME = libgnurl
-!endif
-
-TARGETS = curl.exe
-
-CC = wcc386
-LD = wlink
-AR = wlib
-RC = wrc
-
-!ifdef __LOADDLL__
-! loaddll wcc386 wccd386
-! loaddll wpp386 wppd386
-! loaddll wlib wlibd
-! loaddll wlink wlinkd
-!endif
-
-!ifdef __UNIX__
-CP = cp
-MD = mkdir -p
-!else
-CP = copy 2>NUL
-MD = mkdir
-!endif
-!if $(__VERSION__) > 1290
-RD = rm -rf
-!else ifdef __UNIX__
-RD = rm -rf
-!else
-RD = rmdir /q /s 2>NUL
-!endif
-
-SYS_INCL = -I"$(%watcom)/h/nt" -I"$(%watcom)/h"
-
-CFLAGS = -3r -mf -hc -zff -zgf -zq -zm -s -fr=con -w2 -fpi -oilrtfm &
- -wcd=201 -bt=nt -bc -d+ -dWIN32 -dHAVE_STRTOLL &
- -I"../include" -I"../lib" $(SYS_INCL)
-
-!ifdef %debug
-DEBUG = -dDEBUG=1 -dDEBUGBUILD
-CFLAGS += -d3 $(DEBUG)
-!else
-CFLAGS += -d0
-!endif
-
-!ifdef %use_ipv6
-CFLAGS += -d_WIN32_WINNT=0x0501 -dENABLE_IPV6
-!endif
-
-!ifdef %use_ssl
-CFLAGS += -wcd=138 -dUSE_OPENSSL -dUSE_OPENSSL -I"$(OPENSSL_ROOT)/inc32"
-!endif
-
-!ifdef %curl_static
-CFLAGS += -DCURL_STATICLIB
-!else
-CFLAGS += -br
-!endif
-
-#
-# Change to suite.
-#
-!ifdef %zlib_root
-ZLIB_ROOT = $(%zlib_root)
-!else
-ZLIB_ROOT = ../../zlib-1.2.8
-!endif
-
-!ifdef %libssh2_root
-LIBSSH2_ROOT = $(%libssh2_root)
-!else
-LIBSSH2_ROOT = ../../libssh2-1.5.0
-!endif
-
-!ifdef %librtmp_root
-LIBRTMP_ROOT = $(%librtmp_root)
-!else
-LIBRTMP_ROOT = ../../rtmpdump-2.3
-!endif
-
-!ifdef %openssl_root
-OPENSSL_ROOT = $(%openssl_root)
-!else
-OPENSSL_ROOT = ../../openssl-1.0.2a
-!endif
-
-!ifdef %ares_root
-ARES_ROOT = $(%ares_root)
-!else
-ARES_ROOT = ../ares
-!endif
-
-OBJ_DIR = WC_Win32.obj
-LINK_ARG = $(OBJ_DIR)/wlink.arg
-
-!include Makefile.inc
-
-OBJS1 = $(OBJ_DIR)/$(CURL_CFILES)
-!ifndef %curl_static
-OBJS1 += $(CURLX_CFILES:../lib/=)
-!endif
-OBJS2 = $(OBJS1: = $(OBJ_DIR)/)
-OBJS = $(OBJS2:.c=.obj)
-
-RESOURCE = $(OBJ_DIR)/curl.res
-
-DIRS = $(OBJ_DIR)
-
-all: tool_hugehelp.c $(DIRS) $(TARGETS) .SYMBOLIC
- @echo Welcome to curl
-
-clean: .SYMBOLIC
- -rm -f $(OBJS)
- -rm -f $(RESOURCE) $(LINK_ARG)
-
-vclean distclean: clean .SYMBOLIC
- -$(RD) $(OBJ_DIR)
- -rm -f curl.exe curl.sym tool_hugehelp.c
-
-tool_hugehelp.c: tool_hugehelp.c.cvs
- $(CP) $[@ $^@
-
-tool_hugehelp.c.cvs: .EXISTSONLY
- $(CP) tool_hugehelp.c $^@
-
-$(DIRS):
- -$(MD) $^@
-
-curl.exe: $(OBJS) $(RESOURCE)
- %create $(LINK_ARG)
- @%append $(LINK_ARG) system nt
-!ifdef %debug
- @%append $(LINK_ARG) debug all
- @%append $(LINK_ARG) option symfile
-!endif
- @%append $(LINK_ARG) option quiet, caseexact, eliminate
- @%append $(LINK_ARG) option map=$(OBJ_DIR)/$^&.map
- @%append $(LINK_ARG) option res=$(RESOURCE)
- @%append $(LINK_ARG) file { $(OBJS) }
-!ifndef %curl_static
- @%append $(LINK_ARG) library ../lib/$(LIBNAME)_imp.lib
-!else
- @%append $(LINK_ARG) library ../lib/$(LIBNAME).lib
- @%append $(LINK_ARG) library wldap32.lib
-! ifdef %use_zlib
- @%append $(LINK_ARG) library '$(ZLIB_ROOT)/zlib.lib'
-! endif
-! ifdef %use_rtmp
- @%append $(LINK_ARG) library '$(LIBRTMP_ROOT)/librtmp/librtmp.lib'
- @%append $(LINK_ARG) library winmm.lib
-! endif
-! ifdef %use_ssh2
- @%append $(LINK_ARG) library '$(LIBSSH2_ROOT)/win32/libssh2.lib'
-! endif
-! ifdef %use_ssl
- @%append $(LINK_ARG) library '$(OPENSSL_ROOT)/out32/libeay32.lib'
- @%append $(LINK_ARG) library '$(OPENSSL_ROOT)/out32/ssleay32.lib'
-! endif
-! ifdef %use_ares
- @%append $(LINK_ARG) library '$(ARES_ROOT)/cares.lib'
-! endif
-! ifdef %use_winidn
-! if $(__VERSION__) > 1290
- @%append $(LINK_ARG) library normaliz.lib
-! else
- @%append $(LINK_ARG) import '_IdnToAscii@20' 'NORMALIZ.DLL'.'IdnToAscii'
- @%append $(LINK_ARG) import '_IdnToUnicode@20' 'NORMALIZ.DLL'.'IdnToUnicode'
-! endif
-! endif
-!endif
-!ifeq USE_WATT32 1
- @%append $(LINK_ARG) library '$(%watt_root)/lib/wattcpw_imp.lib'
-!else
- @%append $(LINK_ARG) library ws2_32.lib
-!endif
- $(LD) name $^@ @$(LINK_ARG)
-
-$(RESOURCE): curl.rc
- $(RC) $(DEBUG) -q -r -zm -bt=nt -I"../include" $(SYS_INCL) $[@ -fo=$^@
-
-# suffix search path - vpath-like hack
-.c: ../lib
-
-.c{$(OBJ_DIR)}.obj:
- $(CC) $(CFLAGS) $[@ -fo=$^@
diff --git a/src/Makefile.am b/src/Makefile.am
index 0623ba116..cfe21f6e4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -5,11 +5,11 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -87,7 +87,7 @@ NROFF=env LC_ALL=C @NROFF@ @MANOPT@ # figured out by the configure script
EXTRA_DIST = mkhelp.pl.in makefile.dj \
Makefile.m32 macos/curl.mcp.xml.sit.hqx macos/MACINSTALL.TXT \
macos/src/curl_GUSIConfig.cpp macos/src/macos_main.cpp makefile.amiga \
- curl.rc Makefile.netware Makefile.inc Makefile.Watcom
+ curl.rc Makefile.netware Makefile.inc CMakeLists.txt
do_subst_perl = $(AWK) -v perl=$(PERL) '{gsub("AWKPERL",perl,$$0); print $$0}'
diff --git a/src/Makefile.inc b/src/Makefile.inc
index b5a3fb2e3..f21be0d30 100644
--- a/src/Makefile.inc
+++ b/src/Makefile.inc
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -36,7 +36,8 @@ GNURLX_CFILES = \
../lib/warnless.c \
../lib/curl_ctype.c \
../lib/curl_multibyte.c \
- ../lib/version_win32.c
+ ../lib/version_win32.c \
+ ../lib/dynbuf.c
GNURLX_HFILES = \
../lib/curl_setup.h \
@@ -45,7 +46,8 @@ GNURLX_HFILES = \
../lib/warnless.h \
../lib/curl_ctype.h \
../lib/curl_multibyte.h \
- ../lib/version_win32.h
+ ../lib/version_win32.h \
+ ../lib/dynbuf.h
GNURL_CFILES = \
slist_wc.c \
diff --git a/src/Makefile.m32 b/src/Makefile.m32
index f5864ebe3..f32bf9ef4 100644
--- a/src/Makefile.m32
+++ b/src/Makefile.m32
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -89,6 +89,14 @@ endif
ifndef NGHTTP2_PATH
NGHTTP2_PATH = ../../nghttp2-1.0.0
endif
+# Edit the path below to point to the base of your nghttp3 package.
+ifndef NGHTTP3_PATH
+NGHTTP3_PATH = ../../nghttp3-1.0.0
+endif
+# Edit the path below to point to the base of your ngtcp2 package.
+ifndef NGTCP2_PATH
+NGTCP2_PATH = ../../ngtcp2-1.0.0
+endif
PROOT = ..
@@ -224,6 +232,15 @@ endif
ifeq ($(findstring -nghttp2,$(CFG)),-nghttp2)
NGHTTP2 = 1
endif
+ifeq ($(findstring -nghttp3,$(CFG)),-nghttp3)
+NGHTTP3 = 1
+endif
+ifeq ($(findstring -ngtcp2,$(CFG)),-ngtcp2)
+NGTCP2 = 1
+endif
+ifeq ($(findstring -unicode,$(CFG)),-unicode)
+UNICODE = 1
+endif
INCLUDES = -I. -I../include -I../lib
ifdef SSL
@@ -231,6 +248,10 @@ ifdef SSL
CFLAGS += -DCURL_WITH_MULTI_SSL
endif
endif
+ifdef UNICODE
+ CFLAGS += -DUNICODE -D_UNICODE
+ LDFLAGS += -municode
+endif
ifdef DYN
curl_DEPENDENCIES = $(PROOT)/lib/libgnurldll.a $(PROOT)/lib/libgnurl.dll
@@ -270,6 +291,15 @@ ifdef SSH2
endif
endif
ifdef SSL
+ ifdef NGHTTP3
+ CFLAGS += -DUSE_NGHTTP3
+ curl_LDADD += -L"$(NGHTTP3_PATH)/lib" -lnghttp3
+ ifdef NGTCP2
+ CFLAGS += -DUSE_NGTCP2
+ curl_LDADD += -L"$(NGTCP2_PATH)/lib" -lngtcp2 -lngtcp2_crypto_openssl
+ endif
+ endif
+
ifndef OPENSSL_INCLUDE
ifeq "$(wildcard $(OPENSSL_PATH)/outinc)" "$(OPENSSL_PATH)/outinc"
OPENSSL_INCLUDE = $(OPENSSL_PATH)/outinc
@@ -312,7 +342,12 @@ endif
ifdef ZSTD
INCLUDES += -I"$(ZSTD_PATH)/include"
CFLAGS += -DHAVE_ZSTD
- curl_LDADD += -L"$(ZSTD_PATH)/lib" -lzstd
+ curl_LDADD += -L"$(ZSTD_PATH)/lib"
+ ifdef ZSTD_LIBS
+ curl_LDADD += $(ZSTD_LIBS)
+ else
+ curl_LDADD += -lzstd
+ endif
endif
ifdef BROTLI
INCLUDES += -I"$(BROTLI_PATH)/include"
@@ -375,10 +410,8 @@ include Makefile.inc
curl_PROGRAMS = curl.exe
curl_OBJECTS := $(patsubst %.c,%.o,$(strip $(CURL_CFILES)))
curlx_OBJECTS := $(patsubst %.c,%.o,$(notdir $(strip $(CURLX_CFILES))))
-ifdef DYN
curl_OBJECTS += $(curlx_OBJECTS)
vpath %.c $(PROOT)/lib
-endif
RESOURCE = curl.res
diff --git a/src/Makefile.netware b/src/Makefile.netware
index 64a0222fd..b44395eca 100644
--- a/src/Makefile.netware
+++ b/src/Makefile.netware
@@ -6,11 +6,11 @@
# \___|\___/|_| \_\_____|
#
# Copyright (C) 2004 - 2014, Guenter Knauf
-# Copyright (C) 2001 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 2001 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -97,7 +97,7 @@ endif
TARGET = curl
VERSION = $(LIBCURL_VERSION)
COPYR = Copyright (C) $(LIBCURL_COPYRIGHT_STR)
-DESCR = curl $(LIBCURL_VERSION_STR) ($(LIBARCH)) - https://curl.haxx.se
+DESCR = curl $(LIBCURL_VERSION_STR) ($(LIBARCH)) - https://curl.se
MTSAFE = YES
STACK = 64000
SCREEN = $(TARGET) commandline utility
diff --git a/src/curl.rc b/src/curl.rc
index 4dac2ae70..7d88b32d9 100644
--- a/src/curl.rc
+++ b/src/curl.rc
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -44,7 +44,7 @@ BEGIN
BEGIN
BLOCK "040904b0"
BEGIN
- VALUE "CompanyName", "curl, https://curl.haxx.se/\0"
+ VALUE "CompanyName", "curl, https://curl.se/\0"
VALUE "FileDescription", "The curl executable\0"
VALUE "FileVersion", CURL_VERSION "\0"
VALUE "InternalName", "curl\0"
@@ -52,7 +52,7 @@ BEGIN
VALUE "ProductName", "The curl executable\0"
VALUE "ProductVersion", CURL_VERSION "\0"
VALUE "LegalCopyright", "\xa9 " CURL_COPYRIGHT "\0" /* a9: Copyright symbol */
- VALUE "License", "https://curl.haxx.se/docs/copyright.html\0"
+ VALUE "License", "https://curl.se/docs/copyright.html\0"
END
END
diff --git a/src/makefile.amiga b/src/makefile.amiga
index 38c426834..acc0aef15 100644
--- a/src/makefile.amiga
+++ b/src/makefile.amiga
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/src/makefile.dj b/src/makefile.dj
index 259d4c908..84fb91daa 100644
--- a/src/makefile.dj
+++ b/src/makefile.dj
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/src/mkhelp.pl.in b/src/mkhelp.pl.in
index 5422ee165..21be40f5b 100755
--- a/src/mkhelp.pl.in
+++ b/src/mkhelp.pl.in
@@ -6,11 +6,11 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/src/slist_wc.c b/src/slist_wc.c
index da25632d1..c1393eeb8 100644
--- a/src/slist_wc.c
+++ b/src/slist_wc.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/slist_wc.h b/src/slist_wc.h
index 54f871bfe..dd7e0b5ea 100644
--- a/src/slist_wc.h
+++ b/src/slist_wc.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_binmode.c b/src/tool_binmode.c
index b88a0fd26..f8559e778 100644
--- a/src/tool_binmode.c
+++ b/src/tool_binmode.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_binmode.h b/src/tool_binmode.h
index 1ff0f76a8..1d84cffbb 100644
--- a/src/tool_binmode.h
+++ b/src/tool_binmode.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_bname.c b/src/tool_bname.c
index 6014c6bd8..c1c3b0d4f 100644
--- a/src/tool_bname.c
+++ b/src/tool_bname.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_bname.h b/src/tool_bname.h
index dfde5897c..3a4ec96c2 100644
--- a/src/tool_bname.h
+++ b/src/tool_bname.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_cb_dbg.c b/src/tool_cb_dbg.c
index 1c42db8a5..6e82e3852 100644
--- a/src/tool_cb_dbg.c
+++ b/src/tool_cb_dbg.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -187,7 +187,7 @@ int tool_debug_cb(CURL *handle, curl_infotype type,
switch(type) {
case CURLINFO_TEXT:
- fprintf(output, "%s== Info: %s", timebuf, data);
+ fprintf(output, "%s== Info: %.*s", timebuf, (int)size, data);
/* FALLTHROUGH */
default: /* in case a new one is introduced to shock us */
return 0;
diff --git a/src/tool_cb_dbg.h b/src/tool_cb_dbg.h
index 8883bb162..c3d3f7b77 100644
--- a/src/tool_cb_dbg.h
+++ b/src/tool_cb_dbg.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_cb_hdr.c b/src/tool_cb_hdr.c
index 5741f0aba..67ea10447 100644
--- a/src/tool_cb_hdr.c
+++ b/src/tool_cb_hdr.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -98,53 +98,27 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
/*
* Write etag to file when --etag-save option is given.
- * etag string that we want is enveloped in double quotes
*/
if(per->config->etag_save_file && etag_save->stream) {
/* match only header that start with etag (case insensitive) */
if(curl_strnequal(str, "etag:", 5)) {
- char *etag_h = NULL;
- char *first = NULL;
- char *last = NULL;
- size_t etag_length = 0;
-
- etag_h = ptr;
- /* point to first occurrence of double quote */
- first = memchr(etag_h, '\"', cb);
-
- /*
- * if server side messed with the etag header and doesn't include
- * double quotes around the etag, kindly exit with a warning
- */
-
- if(!first) {
- warnf(per->config->global,
- "Received header etag is missing double quote/s\n");
- return failure;
- }
- else {
- /* discard first double quote */
- first++;
- }
-
- /* point to last occurrence of double quote */
- last = memchr(first, '\"', cb);
-
- if(!last) {
- warnf(per->config->global,
- "Received header etag is missing double quote/s\n");
- return failure;
+ const char *etag_h = &str[5];
+ const char *eot = end - 1;
+ if(*eot == '\n') {
+ while(ISSPACE(*etag_h) && (etag_h < eot))
+ etag_h++;
+ while(ISSPACE(*eot))
+ eot--;
+
+ if(eot >= etag_h) {
+ size_t etag_length = eot - etag_h + 1;
+ fwrite(etag_h, size, etag_length, etag_save->stream);
+ /* terminate with newline */
+ fputc('\n', etag_save->stream);
+ (void)fflush(etag_save->stream);
+ }
}
-
- /* get length of desired etag */
- etag_length = (size_t)last - (size_t)first;
-
- fwrite(first, size, etag_length, etag_save->stream);
- /* terminate with new line */
- fputc('\n', etag_save->stream);
}
-
- (void)fflush(etag_save->stream);
}
/*
@@ -205,7 +179,17 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
if(!outs->stream && !tool_create_output_file(outs, per->config))
return failure;
}
-
+ if(hdrcbdata->config->writeout) {
+ char *value = memchr(ptr, ':', cb);
+ if(value) {
+ if(per->was_last_header_empty)
+ per->num_headers = 0;
+ per->was_last_header_empty = FALSE;
+ per->num_headers++;
+ }
+ else if(ptr[0] == '\r' || ptr[0] == '\n')
+ per->was_last_header_empty = TRUE;
+ }
if(hdrcbdata->config->show_headers &&
(protocol &
(CURLPROTO_HTTP|CURLPROTO_HTTPS|CURLPROTO_RTSP|CURLPROTO_FILE))) {
diff --git a/src/tool_cb_hdr.h b/src/tool_cb_hdr.h
index ec5772f55..6bb2153b2 100644
--- a/src/tool_cb_hdr.h
+++ b/src/tool_cb_hdr.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_cb_prg.c b/src/tool_cb_prg.c
index aad451b87..50f33aa51 100644
--- a/src/tool_cb_prg.c
+++ b/src/tool_cb_prg.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_cb_prg.h b/src/tool_cb_prg.h
index cc8876849..a6fab323a 100644
--- a/src/tool_cb_prg.h
+++ b/src/tool_cb_prg.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_cb_rea.c b/src/tool_cb_rea.c
index 78a169fb0..eec53b6e3 100644
--- a/src/tool_cb_rea.c
+++ b/src/tool_cb_rea.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_cb_rea.h b/src/tool_cb_rea.h
index 5f7e483a3..ea25f17d4 100644
--- a/src/tool_cb_rea.h
+++ b/src/tool_cb_rea.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_cb_see.c b/src/tool_cb_see.c
index 9d660313e..2163aeaf6 100644
--- a/src/tool_cb_see.c
+++ b/src/tool_cb_see.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_cb_see.h b/src/tool_cb_see.h
index b5b787ed0..edaf81808 100644
--- a/src/tool_cb_see.h
+++ b/src/tool_cb_see.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_cb_wrt.c b/src/tool_cb_wrt.c
index 64b62fefd..d5e96aa0b 100644
--- a/src/tool_cb_wrt.c
+++ b/src/tool_cb_wrt.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -39,6 +39,15 @@
#include "memdebug.h" /* keep this as LAST include */
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+#ifdef WIN32
+#define OPENMODE S_IREAD | S_IWRITE
+#else
+#define OPENMODE S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH
+#endif
+
/* create a local file for writing, return TRUE on success */
bool tool_create_output_file(struct OutStruct *outs,
struct OperationConfig *config)
@@ -55,21 +64,24 @@ bool tool_create_output_file(struct OutStruct *outs,
if(outs->is_cd_filename) {
/* don't overwrite existing files */
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
- int fd = open(outs->filename, O_CREAT | O_WRONLY | O_EXCL | O_BINARY,
-#ifdef WIN32
- S_IREAD | S_IWRITE
-#else
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH
-#endif
- );
+ int fd;
+ char *name = outs->filename;
+ char *aname = NULL;
+ if(config->output_dir) {
+ aname = aprintf("%s/%s", config->output_dir, name);
+ if(!aname) {
+ errorf(global, "out of memory\n");
+ return FALSE;
+ }
+ name = aname;
+ }
+ fd = open(name, O_CREAT | O_WRONLY | O_EXCL | O_BINARY, OPENMODE);
if(fd != -1) {
file = fdopen(fd, "wb");
if(!file)
close(fd);
}
+ free(aname);
}
else
/* open file for writing */
diff --git a/src/tool_cb_wrt.h b/src/tool_cb_wrt.h
index e49d8f35d..95a11ebbe 100644
--- a/src/tool_cb_wrt.h
+++ b/src/tool_cb_wrt.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_cfgable.c b/src/tool_cfgable.c
index 63bdeaa46..4c06d3557 100644
--- a/src/tool_cfgable.c
+++ b/src/tool_cfgable.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -44,6 +44,7 @@ void config_init(struct OperationConfig *config)
config->tcp_nodelay = TRUE; /* enabled by default */
config->happy_eyeballs_timeout_ms = CURL_HET_DEFAULT;
config->http09_allowed = FALSE;
+ config->ftp_skip_ip = TRUE;
}
static void free_config_fields(struct OperationConfig *config)
@@ -54,6 +55,7 @@ static void free_config_fields(struct OperationConfig *config)
Curl_safefree(config->egd_file);
Curl_safefree(config->useragent);
Curl_safefree(config->altsvc);
+ Curl_safefree(config->hsts);
Curl_safefree(config->cookie);
Curl_safefree(config->cookiejar);
Curl_safefree(config->cookiefile);
@@ -89,6 +91,7 @@ static void free_config_fields(struct OperationConfig *config)
Curl_safefree(config->mail_auth);
Curl_safefree(config->netrc_file);
+ Curl_safefree(config->output_dir);
urlnode = config->url_list;
while(urlnode) {
diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h
index 4a90d0b72..6b7f874e1 100644
--- a/src/tool_cfgable.h
+++ b/src/tool_cfgable.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -58,6 +58,7 @@ struct OperationConfig {
char *cookiejar; /* write to this file */
char *cookiefile; /* read from this file */
char *altsvc; /* alt-svc cache file name */
+ char *hsts; /* HSTS cache file name */
bool cookiesession; /* new session? */
bool encoding; /* Accept-Encoding please */
bool tr_encoding; /* Transfer-Encoding please */
@@ -80,6 +81,7 @@ struct OperationConfig {
double connecttimeout;
long maxredirs;
curl_off_t max_filesize;
+ char *output_dir;
char *headerfile;
char *ftpport;
char *iface;
@@ -161,6 +163,7 @@ struct OperationConfig {
char *etag_compare_file;
bool crlf;
char *customrequest;
+ char *ssl_ec_curves;
char *krblevel;
char *request_target;
long httpversion;
@@ -310,6 +313,7 @@ struct GlobalConfig {
bool parallel;
long parallel_max;
bool parallel_connect;
+ char *help_category; /* The help category, if set */
struct OperationConfig *first;
struct OperationConfig *current;
struct OperationConfig *last; /* Always last in the struct */
diff --git a/src/tool_convert.c b/src/tool_convert.c
index 3969130c1..26ec07399 100644
--- a/src/tool_convert.c
+++ b/src/tool_convert.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_convert.h b/src/tool_convert.h
index 6d78ecf9d..59db7646b 100644
--- a/src/tool_convert.h
+++ b/src/tool_convert.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_dirhie.c b/src/tool_dirhie.c
index 320fb3688..bf11005e0 100644
--- a/src/tool_dirhie.c
+++ b/src/tool_dirhie.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_dirhie.h b/src/tool_dirhie.h
index 96fae9ebf..c0ef1fcda 100644
--- a/src/tool_dirhie.h
+++ b/src/tool_dirhie.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_doswin.c b/src/tool_doswin.c
index dd8341ae3..2ae6ba788 100644
--- a/src/tool_doswin.c
+++ b/src/tool_doswin.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_doswin.h b/src/tool_doswin.h
index ab23f8d65..ecf952b79 100644
--- a/src/tool_doswin.h
+++ b/src/tool_doswin.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_easysrc.c b/src/tool_easysrc.c
index e8f514fc3..86c113b34 100644
--- a/src/tool_easysrc.c
+++ b/src/tool_easysrc.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -48,7 +48,7 @@ int easysrc_slist_count = 0;
static const char *const srchead[]={
"/********* Sample code generated by the curl command line tool **********",
" * All curl_easy_setopt() options are documented at:",
- " * https://curl.haxx.se/libcurl/c/curl_easy_setopt.html",
+ " * https://curl.se/libcurl/c/curl_easy_setopt.html",
" ************************************************************************/",
"#include <gnurl/curl.h>",
"",
@@ -113,7 +113,7 @@ CURLcode easysrc_addf(struct slist_wc **plist, const char *fmt, ...)
va_start(ap, fmt);
bufp = curlx_mvaprintf(fmt, ap);
va_end(ap);
- if(! bufp) {
+ if(!bufp) {
ret = CURLE_OUT_OF_MEMORY;
}
else {
diff --git a/src/tool_easysrc.h b/src/tool_easysrc.h
index fd799ab84..86bdfa26e 100644
--- a/src/tool_easysrc.h
+++ b/src/tool_easysrc.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_filetime.c b/src/tool_filetime.c
index 1ffc981fe..6d81588e9 100644
--- a/src/tool_filetime.c
+++ b/src/tool_filetime.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -29,6 +29,11 @@
# include <sys/utime.h>
#endif
+#if defined(__GNUC__) && defined(__MINGW32__)
+/* GCC 10 on mingw has issues with this, disable */
+#pragma GCC diagnostic ignored "-Wformat"
+#endif
+
curl_off_t getfiletime(const char *filename, FILE *error_stream)
{
curl_off_t result = -1;
diff --git a/src/tool_filetime.h b/src/tool_filetime.h
index f23afcf30..c75dc57e5 100644
--- a/src/tool_filetime.h
+++ b/src/tool_filetime.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_formparse.c b/src/tool_formparse.c
index 8e8fe874e..1ba6536a1 100644
--- a/src/tool_formparse.c
+++ b/src/tool_formparse.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_formparse.h b/src/tool_formparse.h
index 5c1525e67..7fb41070f 100644
--- a/src/tool_formparse.h
+++ b/src/tool_formparse.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
index 0648c29b9..b7cfeb62e 100644
--- a/src/tool_getparam.c
+++ b/src/tool_getparam.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -219,6 +219,7 @@ static const struct LongShort aliases[]= {
{"A", "user-agent", ARG_STRING},
{"b", "cookie", ARG_STRING},
{"ba", "alt-svc", ARG_STRING},
+ {"bb", "hsts", ARG_STRING},
{"B", "use-ascii", ARG_BOOL},
{"c", "cookie-jar", ARG_STRING},
{"C", "continue-at", ARG_STRING},
@@ -272,6 +273,7 @@ static const struct LongShort aliases[]= {
{"EB", "socks5-gssapi", ARG_BOOL},
{"EC", "etag-save", ARG_FILENAME},
{"ED", "etag-compare", ARG_FILENAME},
+ {"EE", "curves", ARG_STRING},
{"f", "fail", ARG_BOOL},
{"fa", "fail-early", ARG_BOOL},
{"fb", "styled-output", ARG_BOOL},
@@ -303,6 +305,7 @@ static const struct LongShort aliases[]= {
{"o", "output", ARG_FILENAME},
{"O", "remote-name", ARG_NONE},
{"Oa", "remote-name-all", ARG_BOOL},
+ {"Ob", "output-dir", ARG_STRING},
{"p", "proxytunnel", ARG_BOOL},
{"P", "ftp-port", ARG_STRING},
{"q", "disable", ARG_BOOL},
@@ -1267,11 +1270,11 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
break;
case '4':
/* IPv4 */
- config->ip_version = 4;
+ config->ip_version = CURL_IPRESOLVE_V4;
break;
case '6':
/* IPv6 */
- config->ip_version = 6;
+ config->ip_version = CURL_IPRESOLVE_V6;
break;
case 'a':
/* This makes the FTP sessions use APPE instead of STOR */
@@ -1289,6 +1292,12 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
else
return PARAM_LIBCURL_DOESNT_SUPPORT;
break;
+ case 'b': /* --hsts */
+ if(curlinfo->features & CURL_VERSION_HSTS)
+ GetStr(&config->hsts, nextarg);
+ else
+ return PARAM_LIBCURL_DOESNT_SUPPORT;
+ break;
default: /* --cookie string coming up: */
if(nextarg[0] == '@') {
nextarg++;
@@ -1725,6 +1734,10 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
GetStr(&config->etag_compare_file, nextarg);
break;
+ case 'E':
+ GetStr(&config->ssl_ec_curves, nextarg);
+ break;
+
default: /* unknown flag */
return PARAM_OPTION_UNKNOWN;
}
@@ -1771,6 +1784,11 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
case 'h': /* h for help */
if(toggle) {
+ if(nextarg) {
+ global->help_category = strdup(nextarg);
+ if(!global->help_category)
+ return PARAM_NO_MEM;
+ }
return PARAM_HELP_REQUESTED;
}
/* we now actually support --no-help too! */
@@ -1911,6 +1929,10 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
config->default_node_flags = toggle?GETOUT_USEREMOTE:0;
break;
}
+ else if(subletter == 'b') { /* --output-dir */
+ GetStr(&config->output_dir, nextarg);
+ break;
+ }
/* FALLTHROUGH */
case 'o': /* --output */
/* output file */
diff --git a/src/tool_getparam.h b/src/tool_getparam.h
index f6fcd5a35..2c24d4835 100644
--- a/src/tool_getparam.h
+++ b/src/tool_getparam.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_getpass.c b/src/tool_getpass.c
index d3bd4e688..4c50a12d9 100644
--- a/src/tool_getpass.c
+++ b/src/tool_getpass.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -100,11 +100,7 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
#define DONE
#endif /* __VMS */
-#ifdef __SYMBIAN32__
-# define getch() getchar()
-#endif
-
-#if defined(WIN32) || defined(__SYMBIAN32__)
+#if defined(WIN32)
char *getpass_r(const char *prompt, char *buffer, size_t buflen)
{
@@ -123,10 +119,8 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
previous one as well */
i = i - (i >= 1 ? 2 : 1);
}
-#ifndef __SYMBIAN32__
/* since echo is disabled, print a newline */
fputs("\n", stderr);
-#endif
/* if user didn't hit ENTER, terminate buffer */
if(i == buflen)
buffer[buflen-1] = '\0';
@@ -134,7 +128,7 @@ char *getpass_r(const char *prompt, char *buffer, size_t buflen)
return buffer; /* we always return success */
}
#define DONE
-#endif /* WIN32 || __SYMBIAN32__ */
+#endif /* WIN32 */
#ifdef NETWARE
/* NetWare implementation */
diff --git a/src/tool_getpass.h b/src/tool_getpass.h
index f639596fc..d4b35e7f3 100644
--- a/src/tool_getpass.h
+++ b/src/tool_getpass.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_help.c b/src/tool_help.c
index 0fc818d3c..a3323cd59 100644
--- a/src/tool_help.c
+++ b/src/tool_help.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -36,6 +36,76 @@
#endif
/*
+ * The bitmask output is generated with the following command
+ ------------------------------------------------------------
+ cd $srcroot/docs/cmdline-opts
+ ./gen.pl listcats *.d
+ */
+
+#define CURLHELP_HIDDEN 1u << 0u
+#define CURLHELP_AUTH 1u << 1u
+#define CURLHELP_CONNECTION 1u << 2u
+#define CURLHELP_CURL 1u << 3u
+#define CURLHELP_DNS 1u << 4u
+#define CURLHELP_FILE 1u << 5u
+#define CURLHELP_FTP 1u << 6u
+#define CURLHELP_HTTP 1u << 7u
+#define CURLHELP_IMAP 1u << 8u
+#define CURLHELP_IMPORTANT 1u << 9u
+#define CURLHELP_MISC 1u << 10u
+#define CURLHELP_OUTPUT 1u << 11u
+#define CURLHELP_POP3 1u << 12u
+#define CURLHELP_POST 1u << 13u
+#define CURLHELP_PROXY 1u << 14u
+#define CURLHELP_SCP 1u << 15u
+#define CURLHELP_SFTP 1u << 16u
+#define CURLHELP_SMTP 1u << 17u
+#define CURLHELP_SSH 1u << 18u
+#define CURLHELP_TELNET 1u << 19u
+#define CURLHELP_TFTP 1u << 20u
+#define CURLHELP_TLS 1u << 21u
+#define CURLHELP_UPLOAD 1u << 22u
+#define CURLHELP_VERBOSE 1u << 23u
+
+typedef unsigned int curlhelp_t;
+
+struct category_descriptors {
+ const char *opt;
+ const char *desc;
+ curlhelp_t category;
+};
+
+static const struct category_descriptors categories[] = {
+ {"auth", "Different types of authentication methods", CURLHELP_AUTH},
+ {"connection", "Low level networking operations",
+ CURLHELP_CONNECTION},
+ {"curl", "The command line tool itself", CURLHELP_CURL},
+ {"dns", "General DNS options", CURLHELP_DNS},
+ {"file", "FILE protocol options", CURLHELP_FILE},
+ {"ftp", "FTP protocol options", CURLHELP_FTP},
+ {"http", "HTTP and HTTPS protocol options", CURLHELP_HTTP},
+ {"imap", "IMAP protocol options", CURLHELP_IMAP},
+ /* important is left out because it is the default help page */
+ {"misc", "Options that don't fit into any other category", CURLHELP_MISC},
+ {"output", "Filesystem output", CURLHELP_OUTPUT},
+ {"pop3", "POP3 protocol options", CURLHELP_POP3},
+ {"post", "HTTP Post specific options", CURLHELP_POST},
+ {"proxy", "All options related to proxies", CURLHELP_PROXY},
+ {"scp", "SCP protocol options", CURLHELP_SCP},
+ {"sftp", "SFTP protocol options", CURLHELP_SFTP},
+ {"smtp", "SMTP protocol options", CURLHELP_SMTP},
+ {"ssh", "SSH protocol options", CURLHELP_SSH},
+ {"telnet", "TELNET protocol options", CURLHELP_TELNET},
+ {"tftp", "TFTP protocol options", CURLHELP_TFTP},
+ {"tls", "All TLS/SSL related options", CURLHELP_TLS},
+ {"upload", "All options for uploads",
+ CURLHELP_UPLOAD},
+ {"verbose", "Options related to any kind of command line output of curl",
+ CURLHELP_VERBOSE},
+ {NULL, NULL, CURLHELP_HIDDEN}
+};
+
+/*
* The help output is generated with the following command
---------------------------------------------------------
@@ -46,485 +116,723 @@
struct helptxt {
const char *opt;
const char *desc;
+ curlhelp_t categories;
};
static const struct helptxt helptext[] = {
{" --abstract-unix-socket <path>",
- "Connect via abstract Unix domain socket"},
+ "Connect via abstract Unix domain socket",
+ CURLHELP_CONNECTION},
{" --alt-svc <file name>",
- "Enable alt-svc with this cache file"},
+ "Enable alt-svc with this cache file",
+ CURLHELP_HTTP},
{" --anyauth",
- "Pick any authentication method"},
+ "Pick any authentication method",
+ CURLHELP_HTTP | CURLHELP_PROXY | CURLHELP_AUTH},
{"-a, --append",
- "Append to target file when uploading"},
+ "Append to target file when uploading",
+ CURLHELP_FTP | CURLHELP_SFTP},
{" --basic",
- "Use HTTP Basic Authentication"},
+ "Use HTTP Basic Authentication",
+ CURLHELP_AUTH},
{" --cacert <file>",
- "CA certificate to verify peer against"},
+ "CA certificate to verify peer against",
+ CURLHELP_TLS},
{" --capath <dir>",
- "CA directory to verify peer against"},
+ "CA directory to verify peer against",
+ CURLHELP_TLS},
{"-E, --cert <certificate[:password]>",
- "Client certificate file and password"},
+ "Client certificate file and password",
+ CURLHELP_TLS},
{" --cert-status",
- "Verify the status of the server certificate"},
+ "Verify the status of the server certificate",
+ CURLHELP_TLS},
{" --cert-type <type>",
- "Certificate type (DER/PEM/ENG)"},
+ "Certificate type (DER/PEM/ENG)",
+ CURLHELP_TLS},
{" --ciphers <list of ciphers>",
- "SSL ciphers to use"},
+ "SSL ciphers to use",
+ CURLHELP_TLS},
{" --compressed",
- "Request compressed response"},
+ "Request compressed response",
+ CURLHELP_HTTP},
{" --compressed-ssh",
- "Enable SSH compression"},
+ "Enable SSH compression",
+ CURLHELP_SCP | CURLHELP_SSH},
{"-K, --config <file>",
- "Read config from a file"},
+ "Read config from a file",
+ CURLHELP_CURL},
{" --connect-timeout <seconds>",
- "Maximum time allowed for connection"},
+ "Maximum time allowed for connection",
+ CURLHELP_CONNECTION},
{" --connect-to <HOST1:PORT1:HOST2:PORT2>",
- "Connect to host"},
+ "Connect to host",
+ CURLHELP_CONNECTION},
{"-C, --continue-at <offset>",
- "Resumed transfer offset"},
+ "Resumed transfer offset",
+ CURLHELP_CONNECTION},
{"-b, --cookie <data|filename>",
- "Send cookies from string/file"},
+ "Send cookies from string/file",
+ CURLHELP_HTTP},
{"-c, --cookie-jar <filename>",
- "Write cookies to <filename> after operation"},
+ "Write cookies to <filename> after operation",
+ CURLHELP_HTTP},
{" --create-dirs",
- "Create necessary local directory hierarchy"},
+ "Create necessary local directory hierarchy",
+ CURLHELP_CURL},
{" --crlf",
- "Convert LF to CRLF in upload"},
+ "Convert LF to CRLF in upload",
+ CURLHELP_FTP | CURLHELP_SMTP},
{" --crlfile <file>",
- "Get a CRL list in PEM format from the given file"},
+ "Get a CRL list in PEM format from the given file",
+ CURLHELP_TLS},
+ {" --curves <algorithm list>",
+ "(EC) TLS key exchange algorithm(s) to request",
+ CURLHELP_TLS},
{"-d, --data <data>",
- "HTTP POST data"},
+ "HTTP POST data",
+ CURLHELP_IMPORTANT | CURLHELP_HTTP | CURLHELP_POST | CURLHELP_UPLOAD},
{" --data-ascii <data>",
- "HTTP POST ASCII data"},
+ "HTTP POST ASCII data",
+ CURLHELP_HTTP | CURLHELP_POST | CURLHELP_UPLOAD},
{" --data-binary <data>",
- "HTTP POST binary data"},
+ "HTTP POST binary data",
+ CURLHELP_HTTP | CURLHELP_POST | CURLHELP_UPLOAD},
{" --data-raw <data>",
- "HTTP POST data, '@' allowed"},
+ "HTTP POST data, '@' allowed",
+ CURLHELP_HTTP | CURLHELP_POST | CURLHELP_UPLOAD},
{" --data-urlencode <data>",
- "HTTP POST data url encoded"},
+ "HTTP POST data url encoded",
+ CURLHELP_HTTP | CURLHELP_POST | CURLHELP_UPLOAD},
{" --delegation <LEVEL>",
- "GSS-API delegation permission"},
+ "GSS-API delegation permission",
+ CURLHELP_AUTH},
{" --digest",
- "Use HTTP Digest Authentication"},
+ "Use HTTP Digest Authentication",
+ CURLHELP_PROXY | CURLHELP_AUTH | CURLHELP_HTTP},
{"-q, --disable",
- "Disable .curlrc"},
+ "Disable .curlrc",
+ CURLHELP_CURL},
{" --disable-eprt",
- "Inhibit using EPRT or LPRT"},
+ "Inhibit using EPRT or LPRT",
+ CURLHELP_FTP},
{" --disable-epsv",
- "Inhibit using EPSV"},
+ "Inhibit using EPSV",
+ CURLHELP_FTP},
{" --disallow-username-in-url",
- "Disallow username in url"},
+ "Disallow username in url",
+ CURLHELP_CURL | CURLHELP_HTTP},
{" --dns-interface <interface>",
- "Interface to use for DNS requests"},
+ "Interface to use for DNS requests",
+ CURLHELP_DNS},
{" --dns-ipv4-addr <address>",
- "IPv4 address to use for DNS requests"},
+ "IPv4 address to use for DNS requests",
+ CURLHELP_DNS},
{" --dns-ipv6-addr <address>",
- "IPv6 address to use for DNS requests"},
+ "IPv6 address to use for DNS requests",
+ CURLHELP_DNS},
{" --dns-servers <addresses>",
- "DNS server addrs to use"},
+ "DNS server addrs to use",
+ CURLHELP_DNS},
{" --doh-url <URL>",
- "Resolve host names over DOH"},
+ "Resolve host names over DOH",
+ CURLHELP_DNS},
{"-D, --dump-header <filename>",
- "Write the received headers to <filename>"},
+ "Write the received headers to <filename>",
+ CURLHELP_HTTP | CURLHELP_FTP},
{" --egd-file <file>",
- "EGD socket path for random data"},
+ "EGD socket path for random data",
+ CURLHELP_TLS},
{" --engine <name>",
- "Crypto engine to use"},
+ "Crypto engine to use",
+ CURLHELP_TLS},
{" --etag-compare <file>",
- "Pass an ETag from a file as a custom header"},
+ "Pass an ETag from a file as a custom header",
+ CURLHELP_HTTP},
{" --etag-save <file>",
- "Parse ETag from a request and save it to a file"},
+ "Parse ETag from a request and save it to a file",
+ CURLHELP_HTTP},
{" --expect100-timeout <seconds>",
- "How long to wait for 100-continue"},
+ "How long to wait for 100-continue",
+ CURLHELP_HTTP},
{"-f, --fail",
- "Fail silently (no output at all) on HTTP errors"},
+ "Fail silently (no output at all) on HTTP errors",
+ CURLHELP_IMPORTANT | CURLHELP_HTTP},
{" --fail-early",
- "Fail on first transfer error, do not continue"},
+ "Fail on first transfer error, do not continue",
+ CURLHELP_CURL},
{" --false-start",
- "Enable TLS False Start"},
+ "Enable TLS False Start",
+ CURLHELP_TLS},
{"-F, --form <name=content>",
- "Specify multipart MIME data"},
+ "Specify multipart MIME data",
+ CURLHELP_HTTP | CURLHELP_UPLOAD},
{" --form-string <name=string>",
- "Specify multipart MIME data"},
+ "Specify multipart MIME data",
+ CURLHELP_HTTP | CURLHELP_UPLOAD},
{" --ftp-account <data>",
- "Account data string"},
+ "Account data string",
+ CURLHELP_FTP | CURLHELP_AUTH},
{" --ftp-alternative-to-user <command>",
- "String to replace USER [name]"},
+ "String to replace USER [name]",
+ CURLHELP_FTP},
{" --ftp-create-dirs",
- "Create the remote dirs if not present"},
+ "Create the remote dirs if not present",
+ CURLHELP_FTP | CURLHELP_SFTP | CURLHELP_CURL},
{" --ftp-method <method>",
- "Control CWD usage"},
+ "Control CWD usage",
+ CURLHELP_FTP},
{" --ftp-pasv",
- "Use PASV/EPSV instead of PORT"},
+ "Use PASV/EPSV instead of PORT",
+ CURLHELP_FTP},
{"-P, --ftp-port <address>",
- "Use PORT instead of PASV"},
+ "Use PORT instead of PASV",
+ CURLHELP_FTP},
{" --ftp-pret",
- "Send PRET before PASV"},
+ "Send PRET before PASV",
+ CURLHELP_FTP},
{" --ftp-skip-pasv-ip",
- "Skip the IP address for PASV"},
+ "Skip the IP address for PASV",
+ CURLHELP_FTP},
{" --ftp-ssl-ccc",
- "Send CCC after authenticating"},
+ "Send CCC after authenticating",
+ CURLHELP_FTP | CURLHELP_TLS},
{" --ftp-ssl-ccc-mode <active/passive>",
- "Set CCC mode"},
+ "Set CCC mode",
+ CURLHELP_FTP | CURLHELP_TLS},
{" --ftp-ssl-control",
- "Require SSL/TLS for FTP login, clear for transfer"},
+ "Require SSL/TLS for FTP login, clear for transfer",
+ CURLHELP_FTP | CURLHELP_TLS},
{"-G, --get",
- "Put the post data in the URL and use GET"},
+ "Put the post data in the URL and use GET",
+ CURLHELP_HTTP | CURLHELP_UPLOAD},
{"-g, --globoff",
- "Disable URL sequences and ranges using {} and []"},
+ "Disable URL sequences and ranges using {} and []",
+ CURLHELP_CURL},
{" --happy-eyeballs-timeout-ms <milliseconds>",
- "Time for IPv6 before trying IPv4"},
+ "Time for IPv6 before trying IPv4",
+ CURLHELP_CONNECTION},
{" --haproxy-protocol",
- "Send HAProxy PROXY protocol v1 header"},
+ "Send HAProxy PROXY protocol v1 header",
+ CURLHELP_HTTP | CURLHELP_PROXY},
{"-I, --head",
- "Show document info only"},
+ "Show document info only",
+ CURLHELP_HTTP | CURLHELP_FTP | CURLHELP_FILE},
{"-H, --header <header/@file>",
- "Pass custom header(s) to server"},
- {"-h, --help",
- "This help text"},
+ "Pass custom header(s) to server",
+ CURLHELP_HTTP},
+ {"-h, --help <category>",
+ "Get help for commands",
+ CURLHELP_IMPORTANT | CURLHELP_CURL},
{" --hostpubmd5 <md5>",
- "Acceptable MD5 hash of the host public key"},
+ "Acceptable MD5 hash of the host public key",
+ CURLHELP_SFTP | CURLHELP_SCP},
+ {" --hsts <file name>",
+ "Enable HSTS with this cache file",
+ CURLHELP_HTTP},
{" --http0.9",
- "Allow HTTP 0.9 responses"},
+ "Allow HTTP 0.9 responses",
+ CURLHELP_HTTP},
{"-0, --http1.0",
- "Use HTTP 1.0"},
+ "Use HTTP 1.0",
+ CURLHELP_HTTP},
{" --http1.1",
- "Use HTTP 1.1"},
+ "Use HTTP 1.1",
+ CURLHELP_HTTP},
{" --http2",
- "Use HTTP 2"},
+ "Use HTTP 2",
+ CURLHELP_HTTP},
{" --http2-prior-knowledge",
- "Use HTTP 2 without HTTP/1.1 Upgrade"},
+ "Use HTTP 2 without HTTP/1.1 Upgrade",
+ CURLHELP_HTTP},
{" --http3",
- "Use HTTP v3"},
+ "Use HTTP v3",
+ CURLHELP_HTTP},
{" --ignore-content-length",
- "Ignore the size of the remote resource"},
+ "Ignore the size of the remote resource",
+ CURLHELP_HTTP | CURLHELP_FTP},
{"-i, --include",
- "Include protocol response headers in the output"},
+ "Include protocol response headers in the output",
+ CURLHELP_IMPORTANT | CURLHELP_VERBOSE},
{"-k, --insecure",
- "Allow insecure server connections when using SSL"},
+ "Allow insecure server connections when using SSL",
+ CURLHELP_TLS},
{" --interface <name>",
- "Use network INTERFACE (or address)"},
+ "Use network INTERFACE (or address)",
+ CURLHELP_CONNECTION},
{"-4, --ipv4",
- "Resolve names to IPv4 addresses"},
+ "Resolve names to IPv4 addresses",
+ CURLHELP_CONNECTION | CURLHELP_DNS},
{"-6, --ipv6",
- "Resolve names to IPv6 addresses"},
+ "Resolve names to IPv6 addresses",
+ CURLHELP_CONNECTION | CURLHELP_DNS},
{"-j, --junk-session-cookies",
- "Ignore session cookies read from file"},
+ "Ignore session cookies read from file",
+ CURLHELP_HTTP},
{" --keepalive-time <seconds>",
- "Interval time for keepalive probes"},
+ "Interval time for keepalive probes",
+ CURLHELP_CONNECTION},
{" --key <key>",
- "Private key file name"},
+ "Private key file name",
+ CURLHELP_TLS | CURLHELP_SSH},
{" --key-type <type>",
- "Private key file type (DER/PEM/ENG)"},
+ "Private key file type (DER/PEM/ENG)",
+ CURLHELP_TLS},
{" --krb <level>",
- "Enable Kerberos with security <level>"},
+ "Enable Kerberos with security <level>",
+ CURLHELP_FTP},
{" --libcurl <file>",
- "Dump libcurl equivalent code of this command line"},
+ "Dump libcurl equivalent code of this command line",
+ CURLHELP_CURL},
{" --limit-rate <speed>",
- "Limit transfer speed to RATE"},
+ "Limit transfer speed to RATE",
+ CURLHELP_CONNECTION},
{"-l, --list-only",
- "List only mode"},
+ "List only mode",
+ CURLHELP_FTP | CURLHELP_POP3},
{" --local-port <num/range>",
- "Force use of RANGE for local port numbers"},
+ "Force use of RANGE for local port numbers",
+ CURLHELP_CONNECTION},
{"-L, --location",
- "Follow redirects"},
+ "Follow redirects",
+ CURLHELP_HTTP},
{" --location-trusted",
- "Like --location, and send auth to other hosts"},
+ "Like --location, and send auth to other hosts",
+ CURLHELP_HTTP | CURLHELP_AUTH},
{" --login-options <options>",
- "Server login options"},
+ "Server login options",
+ CURLHELP_IMAP | CURLHELP_POP3 | CURLHELP_SMTP | CURLHELP_AUTH},
{" --mail-auth <address>",
- "Originator address of the original email"},
+ "Originator address of the original email",
+ CURLHELP_SMTP},
{" --mail-from <address>",
- "Mail from this address"},
+ "Mail from this address",
+ CURLHELP_SMTP},
{" --mail-rcpt <address>",
- "Mail to this address"},
+ "Mail to this address",
+ CURLHELP_SMTP},
{" --mail-rcpt-allowfails",
- "Allow RCPT TO command to fail for some recipients"},
+ "Allow RCPT TO command to fail for some recipients",
+ CURLHELP_SMTP},
{"-M, --manual",
- "Display the full manual"},
+ "Display the full manual",
+ CURLHELP_CURL},
{" --max-filesize <bytes>",
- "Maximum file size to download"},
+ "Maximum file size to download",
+ CURLHELP_CONNECTION},
{" --max-redirs <num>",
- "Maximum number of redirects allowed"},
+ "Maximum number of redirects allowed",
+ CURLHELP_HTTP},
{"-m, --max-time <seconds>",
- "Maximum time allowed for the transfer"},
+ "Maximum time allowed for the transfer",
+ CURLHELP_CONNECTION},
{" --metalink",
- "Process given URLs as metalink XML file"},
+ "Process given URLs as metalink XML file",
+ CURLHELP_MISC},
{" --negotiate",
- "Use HTTP Negotiate (SPNEGO) authentication"},
+ "Use HTTP Negotiate (SPNEGO) authentication",
+ CURLHELP_AUTH | CURLHELP_HTTP},
{"-n, --netrc",
- "Must read .netrc for user name and password"},
+ "Must read .netrc for user name and password",
+ CURLHELP_CURL},
{" --netrc-file <filename>",
- "Specify FILE for netrc"},
+ "Specify FILE for netrc",
+ CURLHELP_CURL},
{" --netrc-optional",
- "Use either .netrc or URL"},
+ "Use either .netrc or URL",
+ CURLHELP_CURL},
{"-:, --next",
- "Make next URL use its separate set of options"},
+ "Make next URL use its separate set of options",
+ CURLHELP_CURL},
{" --no-alpn",
- "Disable the ALPN TLS extension"},
+ "Disable the ALPN TLS extension",
+ CURLHELP_TLS | CURLHELP_HTTP},
{"-N, --no-buffer",
- "Disable buffering of the output stream"},
+ "Disable buffering of the output stream",
+ CURLHELP_CURL},
{" --no-keepalive",
- "Disable TCP keepalive on the connection"},
+ "Disable TCP keepalive on the connection",
+ CURLHELP_CONNECTION},
{" --no-npn",
- "Disable the NPN TLS extension"},
+ "Disable the NPN TLS extension",
+ CURLHELP_TLS | CURLHELP_HTTP},
{" --no-progress-meter",
- "Do not show the progress meter"},
+ "Do not show the progress meter",
+ CURLHELP_VERBOSE},
{" --no-sessionid",
- "Disable SSL session-ID reusing"},
+ "Disable SSL session-ID reusing",
+ CURLHELP_TLS},
{" --noproxy <no-proxy-list>",
- "List of hosts which do not use proxy"},
+ "List of hosts which do not use proxy",
+ CURLHELP_PROXY},
{" --ntlm",
- "Use HTTP NTLM authentication"},
+ "Use HTTP NTLM authentication",
+ CURLHELP_AUTH | CURLHELP_HTTP},
{" --ntlm-wb",
- "Use HTTP NTLM authentication with winbind"},
+ "Use HTTP NTLM authentication with winbind",
+ CURLHELP_AUTH | CURLHELP_HTTP},
{" --oauth2-bearer <token>",
- "OAuth 2 Bearer Token"},
+ "OAuth 2 Bearer Token",
+ CURLHELP_AUTH},
{"-o, --output <file>",
- "Write to file instead of stdout"},
+ "Write to file instead of stdout",
+ CURLHELP_IMPORTANT | CURLHELP_CURL},
+ {" --output-dir <dir>",
+ "Directory to save files in",
+ CURLHELP_CURL},
{"-Z, --parallel",
- "Perform transfers in parallel"},
+ "Perform transfers in parallel",
+ CURLHELP_CONNECTION | CURLHELP_CURL},
{" --parallel-immediate",
- "Do not wait for multiplexing (with --parallel)"},
+ "Do not wait for multiplexing (with --parallel)",
+ CURLHELP_CONNECTION | CURLHELP_CURL},
{" --parallel-max",
- "Maximum concurrency for parallel transfers"},
+ "Maximum concurrency for parallel transfers",
+ CURLHELP_CONNECTION | CURLHELP_CURL},
{" --pass <phrase>",
- "Pass phrase for the private key"},
+ "Pass phrase for the private key",
+ CURLHELP_SSH | CURLHELP_TLS | CURLHELP_AUTH},
{" --path-as-is",
- "Do not squash .. sequences in URL path"},
+ "Do not squash .. sequences in URL path",
+ CURLHELP_CURL},
{" --pinnedpubkey <hashes>",
- "FILE/HASHES Public key to verify peer against"},
+ "FILE/HASHES Public key to verify peer against",
+ CURLHELP_TLS},
{" --post301",
- "Do not switch to GET after following a 301"},
+ "Do not switch to GET after following a 301",
+ CURLHELP_HTTP | CURLHELP_POST},
{" --post302",
- "Do not switch to GET after following a 302"},
+ "Do not switch to GET after following a 302",
+ CURLHELP_HTTP | CURLHELP_POST},
{" --post303",
- "Do not switch to GET after following a 303"},
+ "Do not switch to GET after following a 303",
+ CURLHELP_HTTP | CURLHELP_POST},
{" --preproxy [protocol://]host[:port]",
- "Use this proxy first"},
+ "Use this proxy first",
+ CURLHELP_PROXY},
{"-#, --progress-bar",
- "Display transfer progress as a bar"},
+ "Display transfer progress as a bar",
+ CURLHELP_VERBOSE},
{" --proto <protocols>",
- "Enable/disable PROTOCOLS"},
+ "Enable/disable PROTOCOLS",
+ CURLHELP_CONNECTION | CURLHELP_CURL},
{" --proto-default <protocol>",
- "Use PROTOCOL for any URL missing a scheme"},
+ "Use PROTOCOL for any URL missing a scheme",
+ CURLHELP_CONNECTION | CURLHELP_CURL},
{" --proto-redir <protocols>",
- "Enable/disable PROTOCOLS on redirect"},
+ "Enable/disable PROTOCOLS on redirect",
+ CURLHELP_CONNECTION | CURLHELP_CURL},
{"-x, --proxy [protocol://]host[:port]",
- "Use this proxy"},
+ "Use this proxy",
+ CURLHELP_PROXY},
{" --proxy-anyauth",
- "Pick any proxy authentication method"},
+ "Pick any proxy authentication method",
+ CURLHELP_PROXY | CURLHELP_AUTH},
{" --proxy-basic",
- "Use Basic authentication on the proxy"},
+ "Use Basic authentication on the proxy",
+ CURLHELP_PROXY | CURLHELP_AUTH},
{" --proxy-cacert <file>",
- "CA certificate to verify peer against for proxy"},
+ "CA certificate to verify peer against for proxy",
+ CURLHELP_PROXY | CURLHELP_TLS},
{" --proxy-capath <dir>",
- "CA directory to verify peer against for proxy"},
+ "CA directory to verify peer against for proxy",
+ CURLHELP_PROXY | CURLHELP_TLS},
{" --proxy-cert <cert[:passwd]>",
- "Set client certificate for proxy"},
+ "Set client certificate for proxy",
+ CURLHELP_PROXY | CURLHELP_TLS},
{" --proxy-cert-type <type>",
- "Client certificate type for HTTPS proxy"},
+ "Client certificate type for HTTPS proxy",
+ CURLHELP_PROXY | CURLHELP_TLS},
{" --proxy-ciphers <list>",
- "SSL ciphers to use for proxy"},
+ "SSL ciphers to use for proxy",
+ CURLHELP_PROXY | CURLHELP_TLS},
{" --proxy-crlfile <file>",
- "Set a CRL list for proxy"},
+ "Set a CRL list for proxy",
+ CURLHELP_PROXY | CURLHELP_TLS},
{" --proxy-digest",
- "Use Digest authentication on the proxy"},
+ "Use Digest authentication on the proxy",
+ CURLHELP_PROXY | CURLHELP_TLS},
{" --proxy-header <header/@file>",
- "Pass custom header(s) to proxy"},
+ "Pass custom header(s) to proxy",
+ CURLHELP_PROXY},
{" --proxy-insecure",
- "Do HTTPS proxy connections without verifying the proxy"},
+ "Do HTTPS proxy connections without verifying the proxy",
+ CURLHELP_PROXY | CURLHELP_TLS},
{" --proxy-key <key>",
- "Private key for HTTPS proxy"},
+ "Private key for HTTPS proxy",
+ CURLHELP_PROXY | CURLHELP_TLS},
{" --proxy-key-type <type>",
- "Private key file type for proxy"},
+ "Private key file type for proxy",
+ CURLHELP_PROXY | CURLHELP_TLS},
{" --proxy-negotiate",
- "Use HTTP Negotiate (SPNEGO) authentication on the proxy"},
+ "Use HTTP Negotiate (SPNEGO) authentication on the proxy",
+ CURLHELP_PROXY | CURLHELP_AUTH},
{" --proxy-ntlm",
- "Use NTLM authentication on the proxy"},
+ "Use NTLM authentication on the proxy",
+ CURLHELP_PROXY | CURLHELP_AUTH},
{" --proxy-pass <phrase>",
- "Pass phrase for the private key for HTTPS proxy"},
+ "Pass phrase for the private key for HTTPS proxy",
+ CURLHELP_PROXY | CURLHELP_TLS | CURLHELP_AUTH},
{" --proxy-pinnedpubkey <hashes>",
- "FILE/HASHES public key to verify proxy with"},
+ "FILE/HASHES public key to verify proxy with",
+ CURLHELP_PROXY | CURLHELP_TLS},
{" --proxy-service-name <name>",
- "SPNEGO proxy service name"},
+ "SPNEGO proxy service name",
+ CURLHELP_PROXY | CURLHELP_TLS},
{" --proxy-ssl-allow-beast",
- "Allow security flaw for interop for HTTPS proxy"},
+ "Allow security flaw for interop for HTTPS proxy",
+ CURLHELP_PROXY | CURLHELP_TLS},
{" --proxy-tls13-ciphers <ciphersuite list>",
- "TLS 1.3 proxy cipher suites"},
+ "TLS 1.3 proxy cipher suites",
+ CURLHELP_PROXY | CURLHELP_TLS},
{" --proxy-tlsauthtype <type>",
- "TLS authentication type for HTTPS proxy"},
+ "TLS authentication type for HTTPS proxy",
+ CURLHELP_PROXY | CURLHELP_TLS | CURLHELP_AUTH},
{" --proxy-tlspassword <string>",
- "TLS password for HTTPS proxy"},
+ "TLS password for HTTPS proxy",
+ CURLHELP_PROXY | CURLHELP_TLS | CURLHELP_AUTH},
{" --proxy-tlsuser <name>",
- "TLS username for HTTPS proxy"},
+ "TLS username for HTTPS proxy",
+ CURLHELP_PROXY | CURLHELP_TLS | CURLHELP_AUTH},
{" --proxy-tlsv1",
- "Use TLSv1 for HTTPS proxy"},
+ "Use TLSv1 for HTTPS proxy",
+ CURLHELP_PROXY | CURLHELP_TLS | CURLHELP_AUTH},
{"-U, --proxy-user <user:password>",
- "Proxy user and password"},
+ "Proxy user and password",
+ CURLHELP_PROXY | CURLHELP_AUTH},
{" --proxy1.0 <host[:port]>",
- "Use HTTP/1.0 proxy on given port"},
+ "Use HTTP/1.0 proxy on given port",
+ CURLHELP_PROXY},
{"-p, --proxytunnel",
- "Operate through an HTTP proxy tunnel (using CONNECT)"},
+ "Operate through an HTTP proxy tunnel (using CONNECT)",
+ CURLHELP_PROXY},
{" --pubkey <key>",
- "SSH Public key file name"},
+ "SSH Public key file name",
+ CURLHELP_SFTP | CURLHELP_SCP | CURLHELP_AUTH},
{"-Q, --quote",
- "Send command(s) to server before transfer"},
+ "Send command(s) to server before transfer",
+ CURLHELP_FTP | CURLHELP_SFTP},
{" --random-file <file>",
- "File for reading random data from"},
+ "File for reading random data from",
+ CURLHELP_MISC},
{"-r, --range <range>",
- "Retrieve only the bytes within RANGE"},
+ "Retrieve only the bytes within RANGE",
+ CURLHELP_HTTP | CURLHELP_FTP | CURLHELP_SFTP | CURLHELP_FILE},
{" --raw",
- "Do HTTP \"raw\"; no transfer decoding"},
+ "Do HTTP \"raw\"; no transfer decoding",
+ CURLHELP_HTTP},
{"-e, --referer <URL>",
- "Referrer URL"},
+ "Referrer URL",
+ CURLHELP_HTTP},
{"-J, --remote-header-name",
- "Use the header-provided filename"},
+ "Use the header-provided filename",
+ CURLHELP_OUTPUT},
{"-O, --remote-name",
- "Write output to a file named as the remote file"},
+ "Write output to a file named as the remote file",
+ CURLHELP_IMPORTANT | CURLHELP_OUTPUT},
{" --remote-name-all",
- "Use the remote file name for all URLs"},
+ "Use the remote file name for all URLs",
+ CURLHELP_OUTPUT},
{"-R, --remote-time",
- "Set the remote file's time on the local output"},
+ "Set the remote file's time on the local output",
+ CURLHELP_OUTPUT},
{"-X, --request <command>",
- "Specify request command to use"},
+ "Specify request command to use",
+ CURLHELP_CONNECTION},
{" --request-target",
- "Specify the target for this request"},
+ "Specify the target for this request",
+ CURLHELP_HTTP},
{" --resolve <host:port:addr[,addr]...>",
- "Resolve the host+port to this address"},
+ "Resolve the host+port to this address",
+ CURLHELP_CONNECTION},
{" --retry <num>",
- "Retry request if transient problems occur"},
+ "Retry request if transient problems occur",
+ CURLHELP_CURL},
{" --retry-all-errors",
- "Retry all errors (use with --retry)"},
+ "Retry all errors (use with --retry)",
+ CURLHELP_CURL},
{" --retry-connrefused",
- "Retry on connection refused (use with --retry)"},
+ "Retry on connection refused (use with --retry)",
+ CURLHELP_CURL},
{" --retry-delay <seconds>",
- "Wait time between retries"},
+ "Wait time between retries",
+ CURLHELP_CURL},
{" --retry-max-time <seconds>",
- "Retry only within this period"},
+ "Retry only within this period",
+ CURLHELP_CURL},
{" --sasl-authzid <identity>",
- "Identity for SASL PLAIN authentication"},
+ "Identity for SASL PLAIN authentication",
+ CURLHELP_AUTH},
{" --sasl-ir",
- "Enable initial response in SASL authentication"},
+ "Enable initial response in SASL authentication",
+ CURLHELP_AUTH},
{" --service-name <name>",
- "SPNEGO service name"},
+ "SPNEGO service name",
+ CURLHELP_MISC},
{"-S, --show-error",
- "Show error even when -s is used"},
+ "Show error even when -s is used",
+ CURLHELP_CURL},
{"-s, --silent",
- "Silent mode"},
+ "Silent mode",
+ CURLHELP_IMPORTANT | CURLHELP_VERBOSE},
{" --socks4 <host[:port]>",
- "SOCKS4 proxy on given host + port"},
+ "SOCKS4 proxy on given host + port",
+ CURLHELP_PROXY},
{" --socks4a <host[:port]>",
- "SOCKS4a proxy on given host + port"},
+ "SOCKS4a proxy on given host + port",
+ CURLHELP_PROXY},
{" --socks5 <host[:port]>",
- "SOCKS5 proxy on given host + port"},
+ "SOCKS5 proxy on given host + port",
+ CURLHELP_PROXY},
{" --socks5-basic",
- "Enable username/password auth for SOCKS5 proxies"},
+ "Enable username/password auth for SOCKS5 proxies",
+ CURLHELP_PROXY | CURLHELP_AUTH},
{" --socks5-gssapi",
- "Enable GSS-API auth for SOCKS5 proxies"},
+ "Enable GSS-API auth for SOCKS5 proxies",
+ CURLHELP_PROXY | CURLHELP_AUTH},
{" --socks5-gssapi-nec",
- "Compatibility with NEC SOCKS5 server"},
+ "Compatibility with NEC SOCKS5 server",
+ CURLHELP_PROXY | CURLHELP_AUTH},
{" --socks5-gssapi-service <name>",
- "SOCKS5 proxy service name for GSS-API"},
+ "SOCKS5 proxy service name for GSS-API",
+ CURLHELP_PROXY | CURLHELP_AUTH},
{" --socks5-hostname <host[:port]>",
- "SOCKS5 proxy, pass host name to proxy"},
+ "SOCKS5 proxy, pass host name to proxy",
+ CURLHELP_PROXY},
{"-Y, --speed-limit <speed>",
- "Stop transfers slower than this"},
+ "Stop transfers slower than this",
+ CURLHELP_CONNECTION},
{"-y, --speed-time <seconds>",
- "Trigger 'speed-limit' abort after this time"},
+ "Trigger 'speed-limit' abort after this time",
+ CURLHELP_CONNECTION},
{" --ssl",
- "Try SSL/TLS"},
+ "Try SSL/TLS",
+ CURLHELP_TLS},
{" --ssl-allow-beast",
- "Allow security flaw to improve interop"},
+ "Allow security flaw to improve interop",
+ CURLHELP_TLS},
{" --ssl-no-revoke",
- "Disable cert revocation checks (Schannel)"},
+ "Disable cert revocation checks (Schannel)",
+ CURLHELP_TLS},
{" --ssl-reqd",
- "Require SSL/TLS"},
+ "Require SSL/TLS",
+ CURLHELP_TLS},
{" --ssl-revoke-best-effort",
- "Ignore missing/offline cert CRL dist points"},
+ "Ignore missing/offline cert CRL dist points",
+ CURLHELP_TLS},
{"-2, --sslv2",
- "Use SSLv2"},
+ "Use SSLv2",
+ CURLHELP_TLS},
{"-3, --sslv3",
- "Use SSLv3"},
+ "Use SSLv3",
+ CURLHELP_TLS},
{" --stderr",
- "Where to redirect stderr"},
+ "Where to redirect stderr",
+ CURLHELP_VERBOSE},
{" --styled-output",
- "Enable styled output for HTTP headers"},
+ "Enable styled output for HTTP headers",
+ CURLHELP_VERBOSE},
{" --suppress-connect-headers",
- "Suppress proxy CONNECT response headers"},
+ "Suppress proxy CONNECT response headers",
+ CURLHELP_PROXY},
{" --tcp-fastopen",
- "Use TCP Fast Open"},
+ "Use TCP Fast Open",
+ CURLHELP_CONNECTION},
{" --tcp-nodelay",
- "Use the TCP_NODELAY option"},
+ "Use the TCP_NODELAY option",
+ CURLHELP_CONNECTION},
{"-t, --telnet-option <opt=val>",
- "Set telnet option"},
+ "Set telnet option",
+ CURLHELP_TELNET},
{" --tftp-blksize <value>",
- "Set TFTP BLKSIZE option"},
+ "Set TFTP BLKSIZE option",
+ CURLHELP_TFTP},
{" --tftp-no-options",
- "Do not send any TFTP options"},
+ "Do not send any TFTP options",
+ CURLHELP_TFTP},
{"-z, --time-cond <time>",
- "Transfer based on a time condition"},
+ "Transfer based on a time condition",
+ CURLHELP_HTTP | CURLHELP_FTP},
{" --tls-max <VERSION>",
- "Set maximum allowed TLS version"},
+ "Set maximum allowed TLS version",
+ CURLHELP_TLS},
{" --tls13-ciphers <ciphersuite list>",
- "TLS 1.3 cipher suites to use"},
+ "TLS 1.3 cipher suites to use",
+ CURLHELP_TLS},
{" --tlsauthtype <type>",
- "TLS authentication type"},
+ "TLS authentication type",
+ CURLHELP_TLS | CURLHELP_AUTH},
{" --tlspassword",
- "TLS password"},
+ "TLS password",
+ CURLHELP_TLS | CURLHELP_AUTH},
{" --tlsuser <name>",
- "TLS user name"},
+ "TLS user name",
+ CURLHELP_TLS | CURLHELP_AUTH},
{"-1, --tlsv1",
- "Use TLSv1.0 or greater"},
+ "Use TLSv1.0 or greater",
+ CURLHELP_TLS},
{" --tlsv1.0",
- "Use TLSv1.0 or greater"},
+ "Use TLSv1.0 or greater",
+ CURLHELP_TLS},
{" --tlsv1.1",
- "Use TLSv1.1 or greater"},
+ "Use TLSv1.1 or greater",
+ CURLHELP_TLS},
{" --tlsv1.2",
- "Use TLSv1.2 or greater"},
+ "Use TLSv1.2 or greater",
+ CURLHELP_TLS},
{" --tlsv1.3",
- "Use TLSv1.3 or greater"},
+ "Use TLSv1.3 or greater",
+ CURLHELP_TLS},
{" --tr-encoding",
- "Request compressed transfer encoding"},
+ "Request compressed transfer encoding",
+ CURLHELP_HTTP},
{" --trace <file>",
- "Write a debug trace to FILE"},
+ "Write a debug trace to FILE",
+ CURLHELP_VERBOSE},
{" --trace-ascii <file>",
- "Like --trace, but without hex output"},
+ "Like --trace, but without hex output",
+ CURLHELP_VERBOSE},
{" --trace-time",
- "Add time stamps to trace/verbose output"},
+ "Add time stamps to trace/verbose output",
+ CURLHELP_VERBOSE},
{" --unix-socket <path>",
- "Connect through this Unix domain socket"},
+ "Connect through this Unix domain socket",
+ CURLHELP_CONNECTION},
{"-T, --upload-file <file>",
- "Transfer local FILE to destination"},
+ "Transfer local FILE to destination",
+ CURLHELP_IMPORTANT | CURLHELP_UPLOAD},
{" --url <url>",
- "URL to work with"},
+ "URL to work with",
+ CURLHELP_CURL},
{"-B, --use-ascii",
- "Use ASCII/text transfer"},
+ "Use ASCII/text transfer",
+ CURLHELP_MISC},
{"-u, --user <user:password>",
- "Server user and password"},
+ "Server user and password",
+ CURLHELP_IMPORTANT | CURLHELP_AUTH},
{"-A, --user-agent <name>",
- "Send User-Agent <name> to server"},
+ "Send User-Agent <name> to server",
+ CURLHELP_IMPORTANT | CURLHELP_HTTP},
{"-v, --verbose",
- "Make the operation more talkative"},
+ "Make the operation more talkative",
+ CURLHELP_IMPORTANT | CURLHELP_VERBOSE},
{"-V, --version",
- "Show version number and quit"},
+ "Show version number and quit",
+ CURLHELP_IMPORTANT | CURLHELP_CURL},
{"-w, --write-out <format>",
- "Use output FORMAT after completion"},
+ "Use output FORMAT after completion",
+ CURLHELP_VERBOSE},
{" --xattr",
- "Store metadata in extended file attributes"},
- { NULL, NULL }
+ "Store metadata in extended file attributes",
+ CURLHELP_MISC},
+ { NULL, NULL, CURLHELP_HIDDEN }
};
#ifdef NETWARE
# define PRINT_LINES_PAUSE 23
#endif
-#ifdef __SYMBIAN32__
-# define PRINT_LINES_PAUSE 16
-#endif
-
struct feat {
const char *name;
int bitmask;
@@ -557,19 +865,65 @@ static const struct feat feats[] = {
{"MultiSSL", CURL_VERSION_MULTI_SSL},
{"PSL", CURL_VERSION_PSL},
{"alt-svc", CURL_VERSION_ALTSVC},
+ {"HSTS", CURL_VERSION_HSTS},
};
-void tool_help(void)
+static void print_category(curlhelp_t category)
+{
+ unsigned int i;
+ for(i = 0; helptext[i].opt; ++i)
+ if(helptext[i].categories & category) {
+ printf(" %-19s %s\n", helptext[i].opt, helptext[i].desc);
+ }
+}
+
+/* Prints category if found. If not, it returns 1 */
+static int get_category_content(const char *category)
+{
+ unsigned int i;
+ for(i = 0; categories[i].opt; ++i)
+ if(curl_strequal(categories[i].opt, category)) {
+ printf("%s: %s\n", categories[i].opt, categories[i].desc);
+ print_category(categories[i].category);
+ return 0;
+ }
+ return 1;
+}
+
+/* Prints all categories and their description */
+static void get_categories(void)
+{
+ unsigned int i;
+ for(i = 0; categories[i].opt; ++i)
+ printf(" %-11s %s\n", categories[i].opt, categories[i].desc);
+}
+
+
+void tool_help(char *category)
{
- int i;
puts("Usage: curl [options...] <url>");
- for(i = 0; helptext[i].opt; i++) {
- printf(" %-19s %s\n", helptext[i].opt, helptext[i].desc);
-#ifdef PRINT_LINES_PAUSE
- if(i && ((i % PRINT_LINES_PAUSE) == 0))
- tool_pressanykey();
-#endif
+ /* If no category was provided */
+ if(!category) {
+ const char *category_note = "\nThis is not the full help, this "
+ "menu is stripped into categories.\nUse \"--help category\" to get "
+ "an overview of all categories.\nFor all options use the manual"
+ " or \"--help all\".";
+ print_category(CURLHELP_IMPORTANT);
+ puts(category_note);
+ }
+ /* Lets print everything if "all" was provided */
+ else if(curl_strequal(category, "all"))
+ /* Print everything except hidden */
+ print_category(~(CURLHELP_HIDDEN));
+ /* Lets handle the string "category" differently to not print an errormsg */
+ else if(curl_strequal(category, "category"))
+ get_categories();
+ /* Otherwise print category and handle the case if the cat was not found */
+ else if(get_category_content(category)) {
+ puts("Invalid category provided, here is a list of all categories:\n");
+ get_categories();
}
+ free(category);
}
static int
diff --git a/src/tool_help.h b/src/tool_help.h
index bfb5dcdf3..39ea2400d 100644
--- a/src/tool_help.h
+++ b/src/tool_help.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -23,7 +23,7 @@
***************************************************************************/
#include "tool_setup.h"
-void tool_help(void);
+void tool_help(char *category);
void tool_list_engines(void);
void tool_version_info(void);
diff --git a/src/tool_helpers.c b/src/tool_helpers.c
index 61788b7f8..8cd2ac58a 100644
--- a/src/tool_helpers.c
+++ b/src/tool_helpers.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_helpers.h b/src/tool_helpers.h
index 67d28be2a..c5e577313 100644
--- a/src/tool_helpers.h
+++ b/src/tool_helpers.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_homedir.c b/src/tool_homedir.c
index 54c92ba6e..c232be2b3 100644
--- a/src/tool_homedir.c
+++ b/src/tool_homedir.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -22,9 +22,17 @@
#include "tool_setup.h"
#ifdef HAVE_PWD_H
+# undef __NO_NET_API /* required for building for AmigaOS */
# include <pwd.h>
#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
#include <gnurl/mprintf.h>
#include "tool_homedir.h"
@@ -45,7 +53,27 @@ static char *GetEnv(const char *variable)
}
/* return the home directory of the current user as an allocated string */
-char *homedir(void)
+
+/*
+ * The original logic found a home dir to use (by checking a range of
+ * environment variables and last using getpwuid) and returned that for the
+ * parent to use.
+ *
+ * With the XDG_CONFIG_HOME support (added much later than the other), this
+ * variable is treated differently in order to not ruin existing installations
+ * even if this environment variable is set. If this variable is set, and a
+ * file name is set to check, then only if that file name exists in that
+ * directory will it be returned as a "home directory".
+ *
+ * 1. use CURL_HOME if set
+ * 2. use XDG_CONFIG_HOME if set and fname is present
+ * 3. use HOME if set
+ * 4. Non-windows: use getpwuid
+ * 5. Windows: use APPDATA if set
+ * 6. Windows: use "USERPROFILE\Application Data" is set
+ */
+
+char *homedir(const char *fname)
{
char *home;
@@ -53,6 +81,22 @@ char *homedir(void)
if(home)
return home;
+ if(fname) {
+ home = GetEnv("XDG_CONFIG_HOME");
+ if(home) {
+ char *c = curl_maprintf("%s" DIR_CHAR "%s", home, fname);
+ if(c) {
+ int fd = open(c, O_RDONLY);
+ curl_free(c);
+ if(fd >= 0) {
+ close(fd);
+ return home;
+ }
+ }
+ free(home);
+ }
+ }
+
home = GetEnv("HOME");
if(home)
return home;
diff --git a/src/tool_homedir.h b/src/tool_homedir.h
index 1f9d54a63..31e38e96a 100644
--- a/src/tool_homedir.h
+++ b/src/tool_homedir.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -23,6 +23,6 @@
***************************************************************************/
#include "tool_setup.h"
-char *homedir(void);
+char *homedir(const char *fname);
#endif /* HEADER_CURL_TOOL_HOMEDIR_H */
diff --git a/src/tool_hugehelp.c.cvs b/src/tool_hugehelp.c.cvs
index d1fb41b86..4fdf089b3 100644
--- a/src/tool_hugehelp.c.cvs
+++ b/src/tool_hugehelp.c.cvs
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_hugehelp.h b/src/tool_hugehelp.h
index 9f9396903..06f73e540 100644
--- a/src/tool_hugehelp.h
+++ b/src/tool_hugehelp.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_libinfo.c b/src/tool_libinfo.c
index de7ec4d18..1b0f98e08 100644
--- a/src/tool_libinfo.c
+++ b/src/tool_libinfo.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_libinfo.h b/src/tool_libinfo.h
index 9563cc3ed..9479e3c0d 100644
--- a/src/tool_libinfo.h
+++ b/src/tool_libinfo.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_main.c b/src/tool_main.c
index ccf098e94..16f513a43 100644
--- a/src/tool_main.c
+++ b/src/tool_main.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -322,11 +322,6 @@ int main(int argc, char *argv[])
/* Start our curl operation */
result = operate(&global, argc, argv);
-#ifdef __SYMBIAN32__
- if(global.showerror)
- tool_pressanykey();
-#endif
-
/* Perform the main cleanup */
main_free(&global);
}
diff --git a/src/tool_main.h b/src/tool_main.h
index a68287ec8..74226ce5a 100644
--- a/src/tool_main.h
+++ b/src/tool_main.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_metalink.c b/src/tool_metalink.c
index 2ad7115db..7da49333c 100644
--- a/src/tool_metalink.c
+++ b/src/tool_metalink.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_metalink.h b/src/tool_metalink.h
index abf75dd17..d03dbf737 100644
--- a/src/tool_metalink.h
+++ b/src/tool_metalink.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_msgs.c b/src/tool_msgs.c
index 48877b30d..184adbae9 100644
--- a/src/tool_msgs.c
+++ b/src/tool_msgs.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_msgs.h b/src/tool_msgs.h
index 2c4afd180..c2ab6064a 100644
--- a/src/tool_msgs.h
+++ b/src/tool_msgs.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_operate.c b/src/tool_operate.c
index 97508e874..90d33e5c3 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -99,7 +99,7 @@ CURLcode curl_easy_perform_ev(CURL *easy);
#endif
#define CURL_CA_CERT_ERRORMSG \
- "More details here: https://curl.haxx.se/docs/sslcerts.html\n\n" \
+ "More details here: https://curl.se/docs/sslcerts.html\n\n" \
"curl failed to verify the legitimacy of the server and therefore " \
"could not\nestablish a secure connection to it. To learn more about " \
"this situation and\nhow to fix it, please visit the web page mentioned " \
@@ -320,8 +320,13 @@ static CURLcode pre_transfer(struct GlobalConfig *global,
if(S_ISREG(fileinfo.st_mode))
uploadfilesize = fileinfo.st_size;
- if(uploadfilesize != -1)
+ if(uploadfilesize != -1) {
+ struct OperationConfig *config = per->config; /* for the macro below */
+#ifdef CURL_DISABLE_LIBCURL_OPTION
+ (void)config;
+#endif
my_setopt(per->curl, CURLOPT_INFILESIZE_LARGE, uploadfilesize);
+ }
per->input.fd = per->infd;
}
return result;
@@ -333,7 +338,8 @@ static CURLcode pre_transfer(struct GlobalConfig *global,
static CURLcode post_per_transfer(struct GlobalConfig *global,
struct per_transfer *per,
CURLcode result,
- bool *retryp)
+ bool *retryp,
+ long *delay) /* milliseconds! */
{
struct OutStruct *outs = &per->outs;
CURL *curl = per->curl;
@@ -343,6 +349,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
return result;
*retryp = FALSE;
+ *delay = 0; /* for no retry, keep it zero */
if(per->infdopen)
close(per->infd);
@@ -467,6 +474,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
switch(response) {
+ case 408: /* Request Timeout */
case 429: /* Too Many Requests (RFC6585) */
case 500: /* Internal Server Error */
case 502: /* Bad Gateway */
@@ -512,10 +520,10 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
static const char * const m[]={
NULL,
"(retrying all errors)",
- "timeout",
- "connection refused",
- "HTTP error",
- "FTP error"
+ ": timeout",
+ ": connection refused",
+ ": HTTP error",
+ ": FTP error"
};
sleeptime = per->retry_sleep;
@@ -529,13 +537,12 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
sleeptime = (long)retry_after * 1000; /* milliseconds */
}
}
- warnf(config->global, "Transient problem: %s "
+ warnf(config->global, "Problem %s. "
"Will retry in %ld seconds. "
"%ld retries left.\n",
m[retry], sleeptime/1000L, per->retry_numretries);
per->retry_numretries--;
- tool_go_sleep(sleeptime);
if(!config->retry_delay) {
per->retry_sleep *= 2;
if(per->retry_sleep > RETRY_SLEEP_MAX)
@@ -578,7 +585,8 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
}
outs->bytes = 0; /* clear for next round */
}
- *retryp = TRUE; /* curl_easy_perform loop */
+ *retryp = TRUE;
+ *delay = sleeptime;
return CURLE_OK;
}
} /* if retry_numretries */
@@ -620,7 +628,7 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
fputs("\n", per->progressbar.out);
if(config->writeout)
- ourWriteOut(per->curl, &per->outs, config->writeout);
+ ourWriteOut(per->curl, per, config->writeout);
/* Close the outs file */
if(outs->fopened && outs->stream) {
@@ -922,7 +930,7 @@ static CURLcode single_transfer(struct GlobalConfig *global,
if((PARAM_OK == file2string(&etag_from_file, file)) &&
etag_from_file) {
- header = aprintf("If-None-Match: \"%s\"", etag_from_file);
+ header = aprintf("If-None-Match: %s", etag_from_file);
Curl_safefree(etag_from_file);
}
else
@@ -1050,6 +1058,15 @@ static CURLcode single_transfer(struct GlobalConfig *global,
}
}
+ if(config->output_dir) {
+ char *d = aprintf("%s/%s", config->output_dir, per->outfile);
+ if(!d) {
+ result = CURLE_WRITE_ERROR;
+ break;
+ }
+ free(per->outfile);
+ per->outfile = d;
+ }
/* Create the directory hierarchy, if not pre-existent to a multiple
file output call */
@@ -1511,6 +1528,9 @@ static CURLcode single_transfer(struct GlobalConfig *global,
if(config->pinnedpubkey)
my_setopt_str(curl, CURLOPT_PINNEDPUBLICKEY, config->pinnedpubkey);
+ if(config->ssl_ec_curves)
+ my_setopt_str(curl, CURLOPT_SSL_EC_CURVES, config->ssl_ec_curves);
+
if(curlinfo->features & CURL_VERSION_SSL) {
/* Check if config->cert is a PKCS#11 URI and set the
* config->cert_type if necessary */
@@ -1691,30 +1711,25 @@ static CURLcode single_transfer(struct GlobalConfig *global,
if(config->path_as_is)
my_setopt(curl, CURLOPT_PATH_AS_IS, 1L);
- if(built_in_protos & (CURLPROTO_SCP|CURLPROTO_SFTP)) {
- if(!config->insecure_ok) {
- char *home;
- char *file;
- result = CURLE_FAILED_INIT;
- home = homedir();
- if(home) {
- file = aprintf("%s/.ssh/known_hosts", home);
- if(file) {
- /* new in curl 7.19.6 */
- result = res_setopt_str(curl, CURLOPT_SSH_KNOWNHOSTS, file);
- curl_free(file);
- if(result == CURLE_UNKNOWN_OPTION)
- /* libssh2 version older than 1.1.1 */
- result = CURLE_OK;
- }
- Curl_safefree(home);
- }
- else {
- errorf(global, "Failed to figure out user's home dir!");
+ if((built_in_protos & (CURLPROTO_SCP|CURLPROTO_SFTP)) &&
+ !config->insecure_ok) {
+ char *home = homedir(NULL);
+ if(home) {
+ char *file = aprintf("%s/.ssh/known_hosts", home);
+ if(file) {
+ /* new in curl 7.19.6 */
+ result = res_setopt_str(curl, CURLOPT_SSH_KNOWNHOSTS, file);
+ curl_free(file);
+ if(result == CURLE_UNKNOWN_OPTION)
+ /* libssh2 version older than 1.1.1 */
+ result = CURLE_OK;
}
+ Curl_safefree(home);
if(result)
break;
}
+ else
+ warnf(global, "No home dir, couldn't find known_hosts file!");
}
if(config->no_body || config->remote_time) {
@@ -1839,12 +1854,7 @@ static CURLcode single_transfer(struct GlobalConfig *global,
my_setopt(curl, CURLOPT_MAXFILESIZE_LARGE,
config->max_filesize);
- if(4 == config->ip_version)
- my_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
- else if(6 == config->ip_version)
- my_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6);
- else
- my_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_WHATEVER);
+ my_setopt(curl, CURLOPT_IPRESOLVE, config->ip_version);
/* new in curl 7.15.5 */
if(config->ftp_ssl_reqd)
@@ -2057,6 +2067,9 @@ static CURLcode single_transfer(struct GlobalConfig *global,
if(config->altsvc)
my_setopt_str(curl, CURLOPT_ALTSVC, config->altsvc);
+ if(config->hsts)
+ my_setopt_str(curl, CURLOPT_HSTS, config->hsts);
+
#ifdef USE_METALINK
if(!metalink && config->use_metalink) {
outs->metalink_parser = metalink_parser_context_new();
@@ -2140,6 +2153,7 @@ static CURLcode add_parallel_transfers(struct GlobalConfig *global,
struct per_transfer *per;
CURLcode result = CURLE_OK;
CURLMcode mcode;
+ bool sleeping = FALSE;
*addedp = FALSE;
*morep = FALSE;
result = create_transfer(global, share, addedp);
@@ -2151,10 +2165,15 @@ static CURLcode add_parallel_transfers(struct GlobalConfig *global,
if(per->added)
/* already added */
continue;
+ if(per->startat && (time(NULL) < per->startat)) {
+ /* this is still delaying */
+ sleeping = TRUE;
+ continue;
+ }
result = pre_transfer(global, per);
if(result)
- break;
+ return result;
/* parallel connect means that we don't set PIPEWAIT since pipewait
will make libcurl prefer multiplexing */
@@ -2175,7 +2194,7 @@ static CURLcode add_parallel_transfers(struct GlobalConfig *global,
all_added++;
*addedp = TRUE;
}
- *morep = per ? TRUE : FALSE;
+ *morep = (per || sleeping) ? TRUE : FALSE;
return CURLE_OK;
}
@@ -2189,6 +2208,7 @@ static CURLcode parallel_transfers(struct GlobalConfig *global,
struct timeval start = tvnow();
bool more_transfers;
bool added_transfers;
+ time_t tick = time(NULL);
multi = curl_multi_init();
if(!multi)
@@ -2211,27 +2231,39 @@ static CURLcode parallel_transfers(struct GlobalConfig *global,
if(!mcode) {
int rc;
CURLMsg *msg;
- bool removed = FALSE;
+ bool checkmore = FALSE;
do {
msg = curl_multi_info_read(multi, &rc);
if(msg) {
bool retry;
+ long delay;
struct per_transfer *ended;
CURL *easy = msg->easy_handle;
result = msg->data.result;
curl_easy_getinfo(easy, CURLINFO_PRIVATE, (void *)&ended);
curl_multi_remove_handle(multi, easy);
- result = post_per_transfer(global, ended, result, &retry);
- if(retry)
- continue;
+ result = post_per_transfer(global, ended, result, &retry, &delay);
progress_finalize(ended); /* before it goes away */
all_added--; /* one fewer added */
- removed = TRUE;
- (void)del_per_transfer(ended);
+ checkmore = TRUE;
+ if(retry) {
+ ended->added = FALSE; /* add it again */
+ /* we delay retries in full integer seconds only */
+ ended->startat = delay ? time(NULL) + delay/1000 : 0;
+ }
+ else
+ (void)del_per_transfer(ended);
}
} while(msg);
- if(removed) {
+ if(!checkmore) {
+ time_t tock = time(NULL);
+ if(tick != tock) {
+ checkmore = TRUE;
+ tick = tock;
+ }
+ }
+ if(checkmore) {
/* one or more transfers completed, add more! */
(void)add_parallel_transfers(global, multi, share,
&more_transfers,
@@ -2271,6 +2303,7 @@ static CURLcode serial_transfers(struct GlobalConfig *global,
return result;
for(per = transfers; per;) {
bool retry;
+ long delay;
bool bailout = FALSE;
result = pre_transfer(global, per);
if(result)
@@ -2293,9 +2326,11 @@ static CURLcode serial_transfers(struct GlobalConfig *global,
/* store the result of the actual transfer */
returncode = result;
- result = post_per_transfer(global, per, result, &retry);
- if(retry)
+ result = post_per_transfer(global, per, result, &retry, &delay);
+ if(retry) {
+ tool_go_sleep(delay);
continue;
+ }
/* Bail out upon critical errors or --fail-early */
if(result || is_fatal_error(returncode) ||
@@ -2470,7 +2505,8 @@ static CURLcode run_all_transfers(struct GlobalConfig *global,
/* cleanup if there are any left */
for(per = transfers; per;) {
bool retry;
- CURLcode result2 = post_per_transfer(global, per, result, &retry);
+ long delay;
+ CURLcode result2 = post_per_transfer(global, per, result, &retry, &delay);
if(!result)
/* don't overwrite the original error */
result = result2;
@@ -2524,7 +2560,7 @@ CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[])
/* Check if we were asked for the help */
if(res == PARAM_HELP_REQUESTED)
- tool_help();
+ tool_help(global->help_category);
/* Check if we were asked for the manual */
/*
else if(res == PARAM_MANUAL_REQUESTED)
diff --git a/src/tool_operate.h b/src/tool_operate.h
index 0fa5adee5..fae978dff 100644
--- a/src/tool_operate.h
+++ b/src/tool_operate.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -51,9 +51,14 @@ struct per_transfer {
struct OutStruct etag_save;
struct InStruct input;
struct HdrCbData hdrcbdata;
+ long num_headers;
+ bool was_last_header_empty;
char errorbuffer[CURL_ERROR_SIZE];
bool added; /* set TRUE when added to the multi handle */
+ time_t startat; /* when doing parallel transfers, this is a retry transfer
+ that has been set to sleep until this time before it
+ should get started (again) */
/* for parallel progress bar */
curl_off_t dltotal;
diff --git a/src/tool_operhlp.c b/src/tool_operhlp.c
index 05c9d864a..ce5fbda05 100644
--- a/src/tool_operhlp.c
+++ b/src/tool_operhlp.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_operhlp.h b/src/tool_operhlp.h
index 1e2f02741..482f6e50a 100644
--- a/src/tool_operhlp.h
+++ b/src/tool_operhlp.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_panykey.c b/src/tool_panykey.c
index 7c519028a..e570ca1b1 100644
--- a/src/tool_panykey.c
+++ b/src/tool_panykey.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -21,7 +21,7 @@
***************************************************************************/
#include "tool_setup.h"
-#if defined(__SYMBIAN32__) || defined(NETWARE)
+#if defined(NETWARE)
#ifdef NETWARE
# ifdef __NOVELL_LIBC__
@@ -37,11 +37,9 @@
void tool_pressanykey(void)
{
-#if defined(__SYMBIAN32__)
- getchar();
-#elif defined(NETWARE)
+#if defined(NETWARE)
pressanykey();
#endif
}
-#endif /* __SYMBIAN32__ || NETWARE */
+#endif /* NETWARE */
diff --git a/src/tool_panykey.h b/src/tool_panykey.h
index e5c6f3930..e1fb1ee9c 100644
--- a/src/tool_panykey.h
+++ b/src/tool_panykey.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -23,14 +23,10 @@
***************************************************************************/
#include "tool_setup.h"
-#if defined(__SYMBIAN32__) || defined(NETWARE)
-
+#if defined(NETWARE)
void tool_pressanykey(void);
-
#else
-
#define tool_pressanykey() Curl_nop_stmt
-
#endif
#endif /* HEADER_CURL_TOOL_PANYKEY_H */
diff --git a/src/tool_paramhlp.c b/src/tool_paramhlp.c
index e57daa2e1..2f43932ec 100644
--- a/src/tool_paramhlp.c
+++ b/src/tool_paramhlp.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -34,6 +34,7 @@
#include "tool_msgs.h"
#include "tool_paramhlp.h"
#include "tool_version.h"
+#include "dynbuf.h"
#include "memdebug.h" /* keep this as LAST include */
@@ -56,100 +57,52 @@ struct getout *new_getout(struct OperationConfig *config)
return node;
}
+#define MAX_FILE2STRING (256*1024*1024) /* big enough ? */
+
ParameterError file2string(char **bufp, FILE *file)
{
- char *string = NULL;
+ struct curlx_dynbuf dyn;
+ curlx_dyn_init(&dyn, MAX_FILE2STRING);
if(file) {
- char *ptr;
- size_t alloc = 512;
- size_t alloc_needed;
char buffer[256];
- size_t stringlen = 0;
- string = calloc(1, alloc);
- if(!string)
- return PARAM_NO_MEM;
while(fgets(buffer, sizeof(buffer), file)) {
- size_t buflen;
- ptr = strchr(buffer, '\r');
+ char *ptr = strchr(buffer, '\r');
if(ptr)
*ptr = '\0';
ptr = strchr(buffer, '\n');
if(ptr)
*ptr = '\0';
- buflen = strlen(buffer);
- alloc_needed = stringlen + buflen + 1;
- if(alloc < alloc_needed) {
-#if SIZEOF_SIZE_T < 8
- if(alloc >= (size_t)SIZE_T_MAX/2) {
- Curl_safefree(string);
- return PARAM_NO_MEM;
- }
-#endif
- /* doubling is enough since the string to add is always max 256 bytes
- and the alloc size start at 512 */
- alloc *= 2;
- ptr = realloc(string, alloc);
- if(!ptr) {
- Curl_safefree(string);
- return PARAM_NO_MEM;
- }
- string = ptr;
- }
- strcpy(string + stringlen, buffer);
- stringlen += buflen;
+ if(curlx_dyn_add(&dyn, buffer))
+ return PARAM_NO_MEM;
}
}
- *bufp = string;
+ *bufp = curlx_dyn_ptr(&dyn);
return PARAM_OK;
}
+#define MAX_FILE2MEMORY (1024*1024*1024) /* big enough ? */
+
ParameterError file2memory(char **bufp, size_t *size, FILE *file)
{
- char *newbuf;
- char *buffer = NULL;
- size_t nused = 0;
-
if(file) {
size_t nread;
- size_t alloc = 512;
+ struct curlx_dynbuf dyn;
+ curlx_dyn_init(&dyn, MAX_FILE2MEMORY);
do {
- if(!buffer || (alloc == nused)) {
- /* size_t overflow detection and avoiding huge files */
- if(alloc >= (SIZE_T_MAX/4)) {
- Curl_safefree(buffer);
+ char buffer[4096];
+ nread = fread(buffer, 1, sizeof(buffer), file);
+ if(nread)
+ if(curlx_dyn_addn(&dyn, buffer, nread))
return PARAM_NO_MEM;
- }
- alloc *= 2;
- /* allocate an extra char, reserved space, for null termination */
- newbuf = realloc(buffer, alloc + 1);
- if(!newbuf) {
- Curl_safefree(buffer);
- return PARAM_NO_MEM;
- }
- buffer = newbuf;
- }
- nread = fread(buffer + nused, 1, alloc-nused, file);
- nused += nread;
} while(nread);
- /* null terminate the buffer in case it's used as a string later */
- buffer[nused] = '\0';
- /* free trailing slack space, if possible */
- if(alloc != nused) {
- newbuf = realloc(buffer, nused + 1);
- if(!newbuf) {
- Curl_safefree(buffer);
- return PARAM_NO_MEM;
- }
- buffer = newbuf;
- }
- /* discard buffer if nothing was read */
- if(!nused) {
- Curl_safefree(buffer); /* no string */
- }
+ *size = curlx_dyn_len(&dyn);
+ *bufp = curlx_dyn_ptr(&dyn);
+ }
+ else {
+ *size = 0;
+ *bufp = NULL;
}
- *size = nused;
- *bufp = buffer;
return PARAM_OK;
}
@@ -460,6 +413,7 @@ ParameterError str2offset(curl_off_t *val, const char *str)
return PARAM_BAD_NUMERIC;
}
+#define MAX_USERPWDLENGTH (100*1024)
static CURLcode checkpasswd(const char *kind, /* for what purpose */
const size_t i, /* operation index */
const bool last, /* TRUE if last operation */
@@ -479,12 +433,11 @@ static CURLcode checkpasswd(const char *kind, /* for what purpose */
if(!psep && **userpwd != ';') {
/* no password present, prompt for one */
- char passwd[256] = "";
+ char passwd[2048] = "";
char prompt[256];
- size_t passwdlen;
- size_t userlen = strlen(*userpwd);
- char *passptr;
+ struct curlx_dynbuf dyn;
+ curlx_dyn_init(&dyn, MAX_USERPWDLENGTH);
if(osep)
*osep = '\0';
@@ -500,22 +453,15 @@ static CURLcode checkpasswd(const char *kind, /* for what purpose */
/* get password */
getpass_r(prompt, passwd, sizeof(passwd));
- passwdlen = strlen(passwd);
-
if(osep)
*osep = ';';
- /* extend the allocated memory area to fit the password too */
- passptr = realloc(*userpwd,
- passwdlen + 1 + /* an extra for the colon */
- userlen + 1); /* an extra for the zero */
- if(!passptr)
+ if(curlx_dyn_addf(&dyn, "%s:%s", *userpwd, passwd))
return CURLE_OUT_OF_MEMORY;
- /* append the password separated with a colon */
- passptr[userlen] = ':';
- memcpy(&passptr[userlen + 1], passwd, passwdlen + 1);
- *userpwd = passptr;
+ /* return the new string */
+ free(*userpwd);
+ *userpwd = curlx_dyn_ptr(&dyn);
}
return CURLE_OK;
diff --git a/src/tool_paramhlp.h b/src/tool_paramhlp.h
index d925b8476..664c8b0f5 100644
--- a/src/tool_paramhlp.h
+++ b/src/tool_paramhlp.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_parsecfg.c b/src/tool_parsecfg.c
index 5aeb2eebf..d26774faf 100644
--- a/src/tool_parsecfg.c
+++ b/src/tool_parsecfg.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -31,6 +31,7 @@
#include "tool_homedir.h"
#include "tool_msgs.h"
#include "tool_parsecfg.h"
+#include "dynbuf.h"
#include "memdebug.h" /* keep this as LAST include */
@@ -39,7 +40,9 @@
#define ISSEP(x,dash) (!dash && (((x) == '=') || ((x) == ':')))
static const char *unslashquote(const char *line, char *param);
-static char *my_get_line(FILE *fp);
+
+#define MAX_CONFIG_LINE_LENGTH (100*1024)
+static bool my_get_line(FILE *fp, struct curlx_dynbuf *, bool *error);
#ifdef WIN32
static FILE *execpath(const char *filename)
@@ -82,7 +85,7 @@ int parseconfig(const char *filename, struct GlobalConfig *global)
if(!filename || !*filename) {
/* NULL or no file name attempts to load .curlrc from the homedir! */
- char *home = homedir(); /* portable homedir finder */
+ char *home = homedir(".curlrc");
#ifndef WIN32
if(home) {
pathalloc = curl_maprintf("%s%s.curlrc", home, DIR_CHAR);
@@ -135,17 +138,23 @@ int parseconfig(const char *filename, struct GlobalConfig *global)
if(file) {
char *line;
- char *aline;
char *option;
char *param;
int lineno = 0;
bool dashed_option;
+ struct curlx_dynbuf buf;
+ bool fileerror;
+ curlx_dyn_init(&buf, MAX_CONFIG_LINE_LENGTH);
- while(NULL != (aline = my_get_line(file))) {
+ while(my_get_line(file, &buf, &fileerror)) {
int res;
bool alloced_param = FALSE;
lineno++;
- line = aline;
+ line = curlx_dyn_ptr(&buf);
+ if(!line) {
+ rc = 1; /* out of memory */
+ break;
+ }
/* line with # in the first non-blank column is a comment! */
while(*line && ISSPACE(*line))
@@ -158,7 +167,7 @@ int parseconfig(const char *filename, struct GlobalConfig *global)
case '\n':
case '*':
case '\0':
- Curl_safefree(aline);
+ curlx_dyn_reset(&buf);
continue;
}
@@ -190,7 +199,6 @@ int parseconfig(const char *filename, struct GlobalConfig *global)
param = malloc(strlen(line) + 1); /* parameter */
if(!param) {
/* out of memory */
- Curl_safefree(aline);
rc = 1;
break;
}
@@ -219,7 +227,7 @@ int parseconfig(const char *filename, struct GlobalConfig *global)
break;
default:
warnf(operation->global, "%s:%d: warning: '%s' uses unquoted "
- "white space in the line that may cause side-effects!\n",
+ "whitespace in the line that may cause side-effects!\n",
filename, lineno, option);
}
}
@@ -280,10 +288,13 @@ int parseconfig(const char *filename, struct GlobalConfig *global)
if(alloced_param)
Curl_safefree(param);
- Curl_safefree(aline);
+ curlx_dyn_reset(&buf);
}
+ curlx_dyn_free(&buf);
if(file != stdin)
fclose(file);
+ if(fileerror)
+ rc = 1;
}
else
rc = 1; /* couldn't open the file */
@@ -335,39 +346,23 @@ static const char *unslashquote(const char *line, char *param)
/*
* Reads a line from the given file, ensuring is NUL terminated.
- * The pointer must be freed by the caller.
- * NULL is returned on an out of memory condition.
*/
-static char *my_get_line(FILE *fp)
+static bool my_get_line(FILE *fp, struct curlx_dynbuf *db,
+ bool *error)
{
char buf[4096];
- char *nl = NULL;
- char *line = NULL;
-
+ *error = FALSE;
do {
- if(NULL == fgets(buf, sizeof(buf), fp))
- break;
- if(!line) {
- line = strdup(buf);
- if(!line)
- return NULL;
+ /* fgets() returns s on success, and NULL on error or when end of file
+ occurs while no characters have been read. */
+ if(!fgets(buf, sizeof(buf), fp))
+ /* only if there's data in the line, return TRUE */
+ return curlx_dyn_len(db) ? TRUE : FALSE;
+ if(curlx_dyn_add(db, buf)) {
+ *error = TRUE; /* error */
+ return FALSE; /* stop reading */
}
- else {
- char *ptr;
- size_t linelen = strlen(line);
- ptr = realloc(line, linelen + strlen(buf) + 1);
- if(!ptr) {
- Curl_safefree(line);
- return NULL;
- }
- line = ptr;
- strcpy(&line[linelen], buf);
- }
- nl = strchr(line, '\n');
- } while(!nl);
+ } while(!strchr(buf, '\n'));
- if(nl)
- *nl = '\0';
-
- return line;
+ return TRUE; /* continue */
}
diff --git a/src/tool_parsecfg.h b/src/tool_parsecfg.h
index 49919a7f2..5748c87e7 100644
--- a/src/tool_parsecfg.h
+++ b/src/tool_parsecfg.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_progress.c b/src/tool_progress.c
index 31cd56ae4..b18f63596 100644
--- a/src/tool_progress.c
+++ b/src/tool_progress.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -227,11 +227,11 @@ bool progress_meter(struct GlobalConfig *global,
}
if(dlknown && all_dltotal)
/* TODO: handle integer overflow */
- msnprintf(dlpercen, sizeof(dlpercen), "%3d",
+ msnprintf(dlpercen, sizeof(dlpercen), "%3" CURL_FORMAT_CURL_OFF_T,
all_dlnow * 100 / all_dltotal);
if(ulknown && all_ultotal)
/* TODO: handle integer overflow */
- msnprintf(ulpercen, sizeof(ulpercen), "%3d",
+ msnprintf(ulpercen, sizeof(ulpercen), "%3" CURL_FORMAT_CURL_OFF_T,
all_ulnow * 100 / all_ultotal);
/* get the transfer speed, the higher of the two */
diff --git a/src/tool_progress.h b/src/tool_progress.h
index 34b609816..da9bdedd2 100644
--- a/src/tool_progress.h
+++ b/src/tool_progress.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_sdecls.h b/src/tool_sdecls.h
index ccc9f5aba..5b251657a 100644
--- a/src/tool_sdecls.h
+++ b/src/tool_sdecls.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_setopt.c b/src/tool_setopt.c
index 9858d49c9..b9c305470 100644
--- a/src/tool_setopt.c
+++ b/src/tool_setopt.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -62,6 +62,11 @@ const struct NameValue setopt_nv_CURL_SOCKS_PROXY[] = {
NVEND,
};
+const struct NameValueUnsigned setopt_nv_CURLHSTS[] = {
+ NV(CURLHSTS_ENABLE),
+ NVEND,
+};
+
const struct NameValueUnsigned setopt_nv_CURLAUTH[] = {
NV(CURLAUTH_ANY), /* combination */
NV(CURLAUTH_ANYSAFE), /* combination */
@@ -219,26 +224,34 @@ static const struct NameValue setopt_nv_CURLNONZERODEFAULTS[] = {
/* Escape string to C string syntax. Return NULL if out of memory.
* Is this correct for those wacky EBCDIC guys? */
-static char *c_escape(const char *str, size_t len)
+
+#define MAX_STRING_LENGTH_OUTPUT 2000
+#define ZERO_TERMINATED -1
+
+static char *c_escape(const char *str, curl_off_t len)
{
const char *s;
unsigned char c;
char *escaped, *e;
+ unsigned int cutoff = 0;
- if(len == CURL_ZERO_TERMINATED)
+ if(len == ZERO_TERMINATED)
len = strlen(str);
- /* Check for possible overflow. */
- if(len > (~(size_t) 0) / 4)
- return NULL;
+ if(len > MAX_STRING_LENGTH_OUTPUT) {
+ /* cap ridiculously long strings */
+ len = MAX_STRING_LENGTH_OUTPUT;
+ cutoff = 3;
+ }
/* Allocate space based on worst-case */
- escaped = malloc(4 * len + 1);
+ escaped = malloc(4 * (size_t)len + 1 + cutoff);
if(!escaped)
return NULL;
e = escaped;
- for(s = str; (c = *s) != '\0'; s++) {
+ for(s = str; len; s++, len--) {
+ c = *s;
if(c == '\n') {
strcpy(e, "\\n");
e += 2;
@@ -259,13 +272,15 @@ static char *c_escape(const char *str, size_t len)
strcpy(e, "\\\"");
e += 2;
}
- else if(! isprint(c)) {
- msnprintf(e, 5, "\\%03o", (unsigned)c);
+ else if(!isprint(c)) {
+ msnprintf(e, 5, "\\x%02x", (unsigned)c);
e += 4;
}
else
*e++ = c;
}
+ while(cutoff--)
+ *e++ = '.';
*e = '\0';
return escaped;
}
@@ -289,7 +304,7 @@ CURLcode tool_setopt_enum(CURL *curl, struct GlobalConfig *config,
if(nv->value == lval)
break; /* found it */
}
- if(! nv->name) {
+ if(!nv->name) {
/* If no definition was found, output an explicit value.
* This could happen if new values are defined and used
* but the NameValue list is not updated. */
@@ -404,7 +419,7 @@ static CURLcode libcurl_generate_slist(struct curl_slist *slist, int *slistno)
CLEAN1("slist%d = NULL;", *slistno);
for(; slist; slist = slist->next) {
Curl_safefree(escaped);
- escaped = c_escape(slist->data, CURL_ZERO_TERMINATED);
+ escaped = c_escape(slist->data, ZERO_TERMINATED);
if(!escaped)
return CURLE_OUT_OF_MEMORY;
DATA3("slist%d = curl_slist_append(slist%d, \"%s\");",
@@ -455,7 +470,7 @@ static CURLcode libcurl_generate_mime_part(CURL *curl,
case TOOLMIME_DATA:
#ifdef CURL_DOES_CONVERSIONS
/* Data will be set in ASCII, thus issue a comment with clear text. */
- escaped = c_escape(part->data, CURL_ZERO_TERMINATED);
+ escaped = c_escape(part->data, ZERO_TERMINATED);
NULL_CHECK(escaped);
CODE1("/* \"%s\" */", escaped);
@@ -474,7 +489,7 @@ static CURLcode libcurl_generate_mime_part(CURL *curl,
#endif
if(!ret) {
Curl_safefree(escaped);
- escaped = c_escape(data, CURL_ZERO_TERMINATED);
+ escaped = c_escape(data, ZERO_TERMINATED);
NULL_CHECK(escaped);
CODE2("curl_mime_data(part%d, \"%s\", CURL_ZERO_TERMINATED);",
mimeno, escaped);
@@ -483,7 +498,7 @@ static CURLcode libcurl_generate_mime_part(CURL *curl,
case TOOLMIME_FILE:
case TOOLMIME_FILEDATA:
- escaped = c_escape(part->data, CURL_ZERO_TERMINATED);
+ escaped = c_escape(part->data, ZERO_TERMINATED);
NULL_CHECK(escaped);
CODE2("curl_mime_filedata(part%d, \"%s\");", mimeno, escaped);
if(part->kind == TOOLMIME_FILEDATA && !filename) {
@@ -508,28 +523,28 @@ static CURLcode libcurl_generate_mime_part(CURL *curl,
if(!ret && part->encoder) {
Curl_safefree(escaped);
- escaped = c_escape(part->encoder, CURL_ZERO_TERMINATED);
+ escaped = c_escape(part->encoder, ZERO_TERMINATED);
NULL_CHECK(escaped);
CODE2("curl_mime_encoder(part%d, \"%s\");", mimeno, escaped);
}
if(!ret && filename) {
Curl_safefree(escaped);
- escaped = c_escape(filename, CURL_ZERO_TERMINATED);
+ escaped = c_escape(filename, ZERO_TERMINATED);
NULL_CHECK(escaped);
CODE2("curl_mime_filename(part%d, \"%s\");", mimeno, escaped);
}
if(!ret && part->name) {
Curl_safefree(escaped);
- escaped = c_escape(part->name, CURL_ZERO_TERMINATED);
+ escaped = c_escape(part->name, ZERO_TERMINATED);
NULL_CHECK(escaped);
CODE2("curl_mime_name(part%d, \"%s\");", mimeno, escaped);
}
if(!ret && part->type) {
Curl_safefree(escaped);
- escaped = c_escape(part->type, CURL_ZERO_TERMINATED);
+ escaped = c_escape(part->type, ZERO_TERMINATED);
NULL_CHECK(escaped);
CODE2("curl_mime_type(part%d, \"%s\");", mimeno, escaped);
}
@@ -623,7 +638,8 @@ CURLcode tool_setopt_slist(CURL *curl, struct GlobalConfig *config,
/* generic setopt wrapper for all other options.
* Some type information is encoded in the tag value. */
-CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *config,
+CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *global,
+ struct OperationConfig *config,
const char *name, CURLoption tag, ...)
{
va_list arg;
@@ -711,14 +727,17 @@ CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *config,
va_end(arg);
- if(config->libcurl && !skip && !ret) {
+ if(global->libcurl && !skip && !ret) {
/* we only use this for real if --libcurl was used */
if(remark)
REM2("%s set to a %s", name, value);
else {
if(escape) {
- escaped = c_escape(value, CURL_ZERO_TERMINATED);
+ curl_off_t len = ZERO_TERMINATED;
+ if(tag == CURLOPT_POSTFIELDS)
+ len = config->postfieldsize;
+ escaped = c_escape(value, len);
NULL_CHECK(escaped);
CODE2("curl_easy_setopt(hnd, %s, \"%s\");", name, escaped);
}
diff --git a/src/tool_setopt.h b/src/tool_setopt.h
index 9fe142cf1..a54e34639 100644
--- a/src/tool_setopt.h
+++ b/src/tool_setopt.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -64,8 +64,10 @@ extern const struct NameValueUnsigned setopt_nv_CURLSSLOPT[];
extern const struct NameValue setopt_nv_CURL_NETRC[];
extern const struct NameValue setopt_nv_CURLPROTO[];
extern const struct NameValueUnsigned setopt_nv_CURLAUTH[];
+extern const struct NameValueUnsigned setopt_nv_CURLHSTS[];
/* Map options to NameValue sets */
+#define setopt_nv_CURLOPT_HSTS_CTRL setopt_nv_CURLHSTS
#define setopt_nv_CURLOPT_HTTP_VERSION setopt_nv_CURL_HTTP_VERSION
#define setopt_nv_CURLOPT_HTTPAUTH setopt_nv_CURLAUTH
#define setopt_nv_CURLOPT_SSLVERSION setopt_nv_CURL_SSLVERSION
@@ -98,14 +100,15 @@ CURLcode tool_setopt_mimepost(CURL *curl, struct GlobalConfig *config,
CURLcode tool_setopt_slist(CURL *curl, struct GlobalConfig *config,
const char *name, CURLoption tag,
struct curl_slist *list);
-CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *config,
+CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *global,
+ struct OperationConfig *config,
const char *name, CURLoption tag, ...);
#define my_setopt(x,y,z) \
- SETOPT_CHECK(tool_setopt(x, FALSE, global, #y, y, z), y)
+ SETOPT_CHECK(tool_setopt(x, FALSE, global, config, #y, y, z), y)
#define my_setopt_str(x,y,z) \
- SETOPT_CHECK(tool_setopt(x, TRUE, global, #y, y, z), y)
+ SETOPT_CHECK(tool_setopt(x, TRUE, global, config, #y, y, z), y)
#define my_setopt_enum(x,y,z) \
SETOPT_CHECK(tool_setopt_enum(x, global, #y, y, setopt_nv_ ## y, z), y)
@@ -122,9 +125,9 @@ CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *config,
#define my_setopt_slist(x,y,z) \
SETOPT_CHECK(tool_setopt_slist(x, global, #y, y, z), y)
-#define res_setopt(x,y,z) tool_setopt(x, FALSE, global, #y, y, z)
+#define res_setopt(x,y,z) tool_setopt(x, FALSE, global, config, #y, y, z)
-#define res_setopt_str(x,y,z) tool_setopt(x, TRUE, global, #y, y, z)
+#define res_setopt_str(x,y,z) tool_setopt(x, TRUE, global, config, #y, y, z)
#else /* CURL_DISABLE_LIBCURL_OPTION */
diff --git a/src/tool_setup.h b/src/tool_setup.h
index 51da5b62e..36b97805a 100644
--- a/src/tool_setup.h
+++ b/src/tool_setup.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_sleep.c b/src/tool_sleep.c
index 0fd74a6d9..c9ed5a3e2 100644
--- a/src/tool_sleep.c
+++ b/src/tool_sleep.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_sleep.h b/src/tool_sleep.h
index 59be6aa33..ac51941c6 100644
--- a/src/tool_sleep.h
+++ b/src/tool_sleep.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_strdup.c b/src/tool_strdup.c
index c8e938d16..83fbc727f 100644
--- a/src/tool_strdup.c
+++ b/src/tool_strdup.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_strdup.h b/src/tool_strdup.h
index e30e40310..82ef0eb61 100644
--- a/src/tool_strdup.h
+++ b/src/tool_strdup.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_urlglob.c b/src/tool_urlglob.c
index 430ca88ba..cfce1732a 100644
--- a/src/tool_urlglob.c
+++ b/src/tool_urlglob.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -28,6 +28,7 @@
#include "tool_doswin.h"
#include "tool_urlglob.h"
#include "tool_vms.h"
+#include "dynbuf.h"
#include "memdebug.h" /* keep this as LAST include */
@@ -607,26 +608,21 @@ CURLcode glob_next_url(char **globbed, struct URLGlob *glob)
return CURLE_OK;
}
+#define MAX_OUTPUT_GLOB_LENGTH (10*1024)
+
CURLcode glob_match_url(char **result, char *filename, struct URLGlob *glob)
{
- char *target;
- size_t allocsize;
char numbuf[18];
char *appendthis = (char *)"";
size_t appendlen = 0;
- size_t stringlen = 0;
+ struct curlx_dynbuf dyn;
*result = NULL;
- /* We cannot use the glob_buffer for storage here since the filename may
- * be longer than the URL we use. We allocate a good start size, then
- * we need to realloc in case of need.
+ /* We cannot use the glob_buffer for storage since the filename may be
+ * longer than the URL we use.
*/
- allocsize = strlen(filename) + 1; /* make it at least one byte to store the
- trailing zero */
- target = malloc(allocsize);
- if(!target)
- return CURLE_OUT_OF_MEMORY;
+ curlx_dyn_init(&dyn, MAX_OUTPUT_GLOB_LENGTH);
while(*filename) {
if(*filename == '#' && ISDIGIT(filename[1])) {
@@ -671,7 +667,7 @@ CURLcode glob_match_url(char **result, char *filename, struct URLGlob *glob)
default:
fprintf(stderr, "internal error: invalid pattern type (%d)\n",
(int)pat->type);
- Curl_safefree(target);
+ curlx_dyn_free(&dyn);
return CURLE_FAILED_INIT;
}
}
@@ -686,36 +682,24 @@ CURLcode glob_match_url(char **result, char *filename, struct URLGlob *glob)
appendthis = filename++;
appendlen = 1;
}
- if(appendlen + stringlen >= allocsize) {
- char *newstr;
- /* we append a single byte to allow for the trailing byte to be appended
- at the end of this function outside the while() loop */
- allocsize = (appendlen + stringlen) * 2;
- newstr = realloc(target, allocsize + 1);
- if(!newstr) {
- Curl_safefree(target);
- return CURLE_OUT_OF_MEMORY;
- }
- target = newstr;
- }
- memcpy(&target[stringlen], appendthis, appendlen);
- stringlen += appendlen;
+ if(curlx_dyn_addn(&dyn, appendthis, appendlen))
+ return CURLE_OUT_OF_MEMORY;
}
- target[stringlen]= '\0';
#if defined(MSDOS) || defined(WIN32)
{
char *sanitized;
- SANITIZEcode sc = sanitize_file_name(&sanitized, target,
+ SANITIZEcode sc = sanitize_file_name(&sanitized, curlx_dyn_ptr(&dyn),
(SANITIZE_ALLOW_PATH |
SANITIZE_ALLOW_RESERVED));
- Curl_safefree(target);
+ curlx_dyn_free(&dyn);
if(sc)
return CURLE_URL_MALFORMAT;
- target = sanitized;
+ *result = sanitized;
+ return CURLE_OK;
}
-#endif /* MSDOS || WIN32 */
-
- *result = target;
+#else
+ *result = curlx_dyn_ptr(&dyn);
return CURLE_OK;
+#endif /* MSDOS || WIN32 */
}
diff --git a/src/tool_urlglob.h b/src/tool_urlglob.h
index 5ed76671e..687f57cad 100644
--- a/src/tool_urlglob.h
+++ b/src/tool_urlglob.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_util.c b/src/tool_util.c
index de98b8282..a7535dbef 100644
--- a/src/tool_util.c
+++ b/src/tool_util.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_util.h b/src/tool_util.h
index 8e4a3f4a6..4cc0b16ae 100644
--- a/src/tool_util.h
+++ b/src/tool_util.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_version.h b/src/tool_version.h
index dff9d273e..b49a5b8d3 100644
--- a/src/tool_version.h
+++ b/src/tool_version.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_vms.c b/src/tool_vms.c
index 7871b20f3..18d20e7ed 100644
--- a/src/tool_vms.c
+++ b/src/tool_vms.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_vms.h b/src/tool_vms.h
index 135936986..34ac2381a 100644
--- a/src/tool_vms.h
+++ b/src/tool_vms.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_writeout.c b/src/tool_writeout.c
index 41441ff30..c12738c43 100644
--- a/src/tool_writeout.c
+++ b/src/tool_writeout.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -38,6 +38,8 @@ static const struct writeoutvar variables[] = {
CURLINFO_RESPONSE_CODE, JSON_LONG},
{"response_code", VAR_HTTP_CODE, 0,
CURLINFO_RESPONSE_CODE, JSON_LONG},
+ {"num_headers", VAR_NUM_HEADERS, 0,
+ 0, JSON_LONG},
{"http_connect", VAR_HTTP_CODE_PROXY, 0,
CURLINFO_HTTP_CONNECTCODE, JSON_LONG},
{"time_total", VAR_TOTAL_TIME, 0,
@@ -104,13 +106,13 @@ static const struct writeoutvar variables[] = {
0, JSON_NONE}
};
-void ourWriteOut(CURL *curl, struct OutStruct *outs, const char *writeinfo)
+void ourWriteOut(CURL *curl, struct per_transfer *per, const char *writeinfo)
{
FILE *stream = stdout;
const char *ptr = writeinfo;
char *stringp = NULL;
long longinfo;
- double doubleinfo;
+ curl_off_t offinfo;
while(ptr && *ptr) {
if('%' == *ptr && ptr[1]) {
@@ -156,6 +158,9 @@ void ourWriteOut(CURL *curl, struct OutStruct *outs, const char *writeinfo)
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &longinfo))
fprintf(stream, "%03ld", longinfo);
break;
+ case VAR_NUM_HEADERS:
+ fprintf(stream, "%ld", per->num_headers);
+ break;
case VAR_HTTP_CODE_PROXY:
if(CURLE_OK ==
curl_easy_getinfo(curl, CURLINFO_HTTP_CONNECTCODE,
@@ -184,65 +189,64 @@ void ourWriteOut(CURL *curl, struct OutStruct *outs, const char *writeinfo)
break;
case VAR_REDIRECT_TIME:
if(CURLE_OK ==
- curl_easy_getinfo(curl, CURLINFO_REDIRECT_TIME,
- &doubleinfo))
- fprintf(stream, "%.6f", doubleinfo);
+ curl_easy_getinfo(curl, CURLINFO_REDIRECT_TIME_T, &offinfo))
+ fprintf(stream, "%" CURL_FORMAT_CURL_OFF_TU, offinfo);
break;
case VAR_TOTAL_TIME:
if(CURLE_OK ==
- curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &doubleinfo))
- fprintf(stream, "%.6f", doubleinfo);
+ curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME_T, &offinfo))
+ fprintf(stream, "%" CURL_FORMAT_CURL_OFF_TU, offinfo);
break;
case VAR_NAMELOOKUP_TIME:
if(CURLE_OK ==
- curl_easy_getinfo(curl, CURLINFO_NAMELOOKUP_TIME,
- &doubleinfo))
- fprintf(stream, "%.6f", doubleinfo);
+ curl_easy_getinfo(curl, CURLINFO_NAMELOOKUP_TIME_T,
+ &offinfo))
+ fprintf(stream, "%" CURL_FORMAT_CURL_OFF_TU, offinfo);
break;
case VAR_CONNECT_TIME:
if(CURLE_OK ==
- curl_easy_getinfo(curl, CURLINFO_CONNECT_TIME, &doubleinfo))
- fprintf(stream, "%.6f", doubleinfo);
+ curl_easy_getinfo(curl, CURLINFO_CONNECT_TIME_T, &offinfo))
+ fprintf(stream, "%" CURL_FORMAT_CURL_OFF_TU, offinfo);
break;
case VAR_APPCONNECT_TIME:
if(CURLE_OK ==
- curl_easy_getinfo(curl, CURLINFO_APPCONNECT_TIME,
- &doubleinfo))
- fprintf(stream, "%.6f", doubleinfo);
+ curl_easy_getinfo(curl, CURLINFO_APPCONNECT_TIME_T,
+ &offinfo))
+ fprintf(stream, "%" CURL_FORMAT_CURL_OFF_TU, offinfo);
break;
case VAR_PRETRANSFER_TIME:
if(CURLE_OK ==
- curl_easy_getinfo(curl, CURLINFO_PRETRANSFER_TIME,
- &doubleinfo))
- fprintf(stream, "%.6f", doubleinfo);
+ curl_easy_getinfo(curl, CURLINFO_PRETRANSFER_TIME_T,
+ &offinfo))
+ fprintf(stream, "%" CURL_FORMAT_CURL_OFF_TU, offinfo);
break;
case VAR_STARTTRANSFER_TIME:
if(CURLE_OK ==
- curl_easy_getinfo(curl, CURLINFO_STARTTRANSFER_TIME,
- &doubleinfo))
- fprintf(stream, "%.6f", doubleinfo);
+ curl_easy_getinfo(curl, CURLINFO_STARTTRANSFER_TIME_T,
+ &offinfo))
+ fprintf(stream, "%" CURL_FORMAT_CURL_OFF_TU, offinfo);
break;
case VAR_SIZE_UPLOAD:
if(CURLE_OK ==
- curl_easy_getinfo(curl, CURLINFO_SIZE_UPLOAD, &doubleinfo))
- fprintf(stream, "%.0f", doubleinfo);
+ curl_easy_getinfo(curl, CURLINFO_SIZE_UPLOAD_T, &offinfo))
+ fprintf(stream, "%" CURL_FORMAT_CURL_OFF_TU, offinfo);
break;
case VAR_SIZE_DOWNLOAD:
if(CURLE_OK ==
- curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD,
- &doubleinfo))
- fprintf(stream, "%.0f", doubleinfo);
+ curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD_T,
+ &offinfo))
+ fprintf(stream, "%" CURL_FORMAT_CURL_OFF_TU, offinfo);
break;
case VAR_SPEED_DOWNLOAD:
if(CURLE_OK ==
- curl_easy_getinfo(curl, CURLINFO_SPEED_DOWNLOAD,
- &doubleinfo))
- fprintf(stream, "%.3f", doubleinfo);
+ curl_easy_getinfo(curl, CURLINFO_SPEED_DOWNLOAD_T,
+ &offinfo))
+ fprintf(stream, "%" CURL_FORMAT_CURL_OFF_TU, offinfo);
break;
case VAR_SPEED_UPLOAD:
if(CURLE_OK ==
- curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, &doubleinfo))
- fprintf(stream, "%.3f", doubleinfo);
+ curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD_T, &offinfo))
+ fprintf(stream, "%" CURL_FORMAT_CURL_OFF_TU, offinfo);
break;
case VAR_CONTENT_TYPE:
if((CURLE_OK ==
@@ -275,14 +279,13 @@ void ourWriteOut(CURL *curl, struct OutStruct *outs, const char *writeinfo)
fprintf(stream, "%ld", longinfo);
break;
case VAR_EFFECTIVE_FILENAME:
- if(outs->filename)
- fprintf(stream, "%s", outs->filename);
+ if(per->outs.filename)
+ fputs(per->outs.filename, stream);
break;
case VAR_PRIMARY_IP:
- if(CURLE_OK ==
- curl_easy_getinfo(curl, CURLINFO_PRIMARY_IP,
- &stringp))
- fprintf(stream, "%s", stringp);
+ if((CURLE_OK == curl_easy_getinfo(curl, CURLINFO_PRIMARY_IP,
+ &stringp)) && stringp)
+ fputs(stringp, stream);
break;
case VAR_PRIMARY_PORT:
if(CURLE_OK ==
@@ -291,10 +294,9 @@ void ourWriteOut(CURL *curl, struct OutStruct *outs, const char *writeinfo)
fprintf(stream, "%ld", longinfo);
break;
case VAR_LOCAL_IP:
- if(CURLE_OK ==
- curl_easy_getinfo(curl, CURLINFO_LOCAL_IP,
- &stringp))
- fprintf(stream, "%s", stringp);
+ if((CURLE_OK == curl_easy_getinfo(curl, CURLINFO_LOCAL_IP,
+ &stringp)) && stringp)
+ fputs(stringp, stream);
break;
case VAR_LOCAL_PORT:
if(CURLE_OK ==
@@ -326,10 +328,9 @@ void ourWriteOut(CURL *curl, struct OutStruct *outs, const char *writeinfo)
}
break;
case VAR_SCHEME:
- if(CURLE_OK ==
- curl_easy_getinfo(curl, CURLINFO_SCHEME,
- &stringp))
- fprintf(stream, "%s", stringp);
+ if((CURLE_OK == curl_easy_getinfo(curl, CURLINFO_SCHEME,
+ &stringp)) && stringp)
+ fputs(stringp, stream);
break;
case VAR_STDOUT:
stream = stdout;
@@ -338,7 +339,7 @@ void ourWriteOut(CURL *curl, struct OutStruct *outs, const char *writeinfo)
stream = stderr;
break;
case VAR_JSON:
- ourWriteOutJSON(variables, curl, outs, stream);
+ ourWriteOutJSON(variables, curl, per, stream);
default:
break;
}
diff --git a/src/tool_writeout.h b/src/tool_writeout.h
index 68bacb9d4..9fb4e167a 100644
--- a/src/tool_writeout.h
+++ b/src/tool_writeout.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -22,6 +22,7 @@
*
***************************************************************************/
#include "tool_setup.h"
+#include "tool_operate.h"
typedef enum {
VAR_NONE, /* must be the first */
@@ -38,6 +39,7 @@ typedef enum {
VAR_HTTP_CODE,
VAR_HTTP_CODE_PROXY,
VAR_HEADER_SIZE,
+ VAR_NUM_HEADERS,
VAR_REQUEST_SIZE,
VAR_EFFECTIVE_METHOD,
VAR_EFFECTIVE_URL,
@@ -80,6 +82,6 @@ struct writeoutvar {
jsontype jsontype;
};
-void ourWriteOut(CURL *curl, struct OutStruct *outs, const char *writeinfo);
+void ourWriteOut(CURL *curl, struct per_transfer *per, const char *writeinfo);
#endif /* HEADER_CURL_TOOL_WRITEOUT_H */
diff --git a/src/tool_writeout_json.c b/src/tool_writeout_json.c
index dfe51b9ff..78e60b7a4 100644
--- a/src/tool_writeout_json.c
+++ b/src/tool_writeout_json.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -103,13 +103,20 @@ static int writeString(FILE *str, CURL *curl, const char *key, CURLINFO ci)
return 0;
}
-static int writeLong(FILE *str, CURL *curl, const char *key, CURLINFO ci)
+static int writeLong(FILE *str, CURL *curl, const char *key, CURLINFO ci,
+ struct per_transfer *per, const struct writeoutvar *wovar)
{
- long val = 0;
- if(CURLE_OK == curl_easy_getinfo(curl, ci, &val)) {
- fprintf(str, "\"%s\":%ld", key, val);
+ if(wovar->id == VAR_NUM_HEADERS) {
+ fprintf(str, "\"%s\":%ld", key, per->num_headers);
return 1;
}
+ else {
+ long val = 0;
+ if(CURLE_OK == curl_easy_getinfo(curl, ci, &val)) {
+ fprintf(str, "\"%s\":%ld", key, val);
+ return 1;
+ }
+ }
return 0;
}
@@ -149,12 +156,13 @@ static int writeVersion(FILE *str, CURL *curl, const char *key, CURLINFO ci)
}
void ourWriteOutJSON(const struct writeoutvar mappings[], CURL *curl,
- struct OutStruct *outs, FILE *stream)
+ struct per_transfer *per, FILE *stream)
{
int i;
fputs("{", stream);
for(i = 0; mappings[i].name != NULL; i++) {
+ const struct writeoutvar *wovar = &mappings[i];
const char *name = mappings[i].name;
CURLINFO cinfo = mappings[i].cinfo;
int ok = 0;
@@ -168,7 +176,7 @@ void ourWriteOutJSON(const struct writeoutvar mappings[], CURL *curl,
ok = writeString(stream, curl, name, cinfo);
break;
case JSON_LONG:
- ok = writeLong(stream, curl, name, cinfo);
+ ok = writeLong(stream, curl, name, cinfo, per, wovar);
break;
case JSON_OFFSET:
ok = writeOffset(stream, curl, name, cinfo);
@@ -177,7 +185,7 @@ void ourWriteOutJSON(const struct writeoutvar mappings[], CURL *curl,
ok = writeTime(stream, curl, name, cinfo);
break;
case JSON_FILENAME:
- ok = writeFilename(stream, name, outs->filename);
+ ok = writeFilename(stream, name, per->outs.filename);
break;
case JSON_VERSION:
ok = writeVersion(stream, curl, name, cinfo);
diff --git a/src/tool_writeout_json.h b/src/tool_writeout_json.h
index d3988d521..cc8c4e585 100644
--- a/src/tool_writeout_json.h
+++ b/src/tool_writeout_json.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -24,7 +24,7 @@
#include "tool_setup.h"
#include "tool_writeout.h"
-void ourWriteOutJSON(const struct writeoutvar mappings[],
- CURL *curl, struct OutStruct *outs, FILE *stream);
+void ourWriteOutJSON(const struct writeoutvar mappings[], CURL *curl,
+ struct per_transfer *per, FILE *stream);
#endif /* HEADER_CURL_TOOL_WRITEOUT_H */
diff --git a/src/tool_xattr.c b/src/tool_xattr.c
index 592d4a120..b6a00cb01 100644
--- a/src/tool_xattr.c
+++ b/src/tool_xattr.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/src/tool_xattr.h b/src/tool_xattr.h
index 0339b9b97..8d741aaab 100644
--- a/src/tool_xattr.h
+++ b/src/tool_xattr.h
@@ -7,11 +7,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 60ce5c262..acd53d3e7 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -26,7 +26,7 @@ add_subdirectory(server)
add_subdirectory(unit)
function(add_runtests targetname test_flags)
- # Use a special '${TFLAGS}' placeholder as last argument which will be
+ # Use a special '$TFLAGS' placeholder as last argument which will be
# replaced by the contents of the environment variable in runtests.pl.
# This is a workaround for CMake's limitation where commands executed by
# 'make' or 'ninja' cannot portably reference environment variables.
@@ -35,13 +35,12 @@ function(add_runtests targetname test_flags)
COMMAND
"${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/runtests.pl"
${test_flags_list}
- "\${TFLAGS}"
+ "\$TFLAGS"
DEPENDS testdeps
VERBATIM USES_TERMINAL
)
endfunction()
-add_runtests(test "")
add_runtests(test-quiet "-a -s")
add_runtests(test-am "-a -am")
add_runtests(test-full "-a -p -r")
diff --git a/tests/FILEFORMAT.md b/tests/FILEFORMAT.md
index c280c852d..ce4459a29 100644
--- a/tests/FILEFORMAT.md
+++ b/tests/FILEFORMAT.md
@@ -40,6 +40,34 @@ server's port number (in ASCII) followed by a space and the hexadecimal byte
%b64[%HTTPPORT %9a]b64%
+## Hexadecimal decoding
+
+In the preprocess stage, a special instruction can be used to have runtests.pl
+generate a sequence of binary bytes.
+
+To insert a sequence of bytes from a hex encoded string, use this syntax:
+
+ %hex[ %XX-encoded data to decode ]hex%
+
+For example, to insert the binary octets 0, 1 and 255 into the test file:
+
+ %hex[ %00%01%FF ]hex%
+
+## Repeat content
+
+In the preprocess stage, a special instruction can be used to have runtests.pl
+generate a repetetive sequence of bytes.
+
+To insert a sequence of repeat bytes, use this syntax to make the `<string>`
+get repeated `<number>` of times. The number has to be 1 or large and the
+string may contain `%HH` hexadecimal codes:
+
+ %repeat[<number> x <string>]%
+
+For example, to insert the word hello a 100 times:
+
+ %repeat[100 x hello]%
+
# Variables
When the test is preprocessed, a range of "variables" in the test file will be
@@ -93,6 +121,7 @@ Available substitute variables include:
- `%TFTP6PORT` - IPv6 port number of the TFTP server
- `%TFTPPORT` - Port number of the TFTP server
- `%USER` - Login ID of the user running the test
+- `%VERSION` - the full version number of the tested curl
# `<testcase>`
@@ -237,6 +266,7 @@ about to issue.
POP3 `CAPA` and SMTP `EHLO` commands
- `AUTH [mechanisms]` - Enables support for SASL authentication and specifies
a list of space separated mechanisms for IMAP, POP3 and SMTP
+- `STOR [msg]` respond with this instead of default after `STOR`
#### For HTTP/HTTPS
@@ -303,6 +333,7 @@ SKIPPED.
Features testable here are:
- `alt-svc`
+- `c-ares`
- `cookies`
- `crypto`
- `debug`
@@ -310,6 +341,7 @@ Features testable here are:
- `getrlimit`
- `GnuTLS`
- `GSS-API`
+- `HSTS`
- `HTTP-auth`
- `http/2`
- `idn`
@@ -380,7 +412,7 @@ Brief test case description, shown when the test runs.
Set the given environment variables to the specified value before the actual
command is run. They are cleared again after the command has been run.
-### `<command [option="no-output/no-include/force-output/binary-trace"] [timeout="secs"][delay="secs"][type="perl"]>`
+### `<command [option="no-output/no-include/force-output/binary-trace"] [timeout="secs"][delay="secs"][type="perl/shell"]>`
Command line to run.
Note that the URL that gets passed to the server actually controls what data
@@ -398,6 +430,9 @@ the address "[1234::ff]" would be treated as test case 255.
Set `type="perl"` to write the test case as a perl script. It implies that
there's no memory debugging and valgrind gets shut off for this test.
+Set `type="shell"` to write the test case as a shell script. It implies that
+there's no memory debugging and valgrind gets shut off for this test.
+
Set `option="no-output"` to prevent the test script to slap on the `--output`
argument that directs the output to a file. The `--output` is also not added
if the verify/stdout section is used.
@@ -425,10 +460,13 @@ parameter is the not negative integer number of seconds for the delay. This
'delay' attribute is intended for very specific test cases, and normally not
needed.
-### `<file name="log/filename">`
+### `<file name="log/filename" [nonewline="yes"]>`
This creates the named file with this content before the test case is run,
which is useful if the test case needs a file to act on.
+If 'nonewline="yes"` is used, the created file will have the final newline
+stripped off.
+
### `<stdin [nonewline="yes"]>`
Pass this given data on stdin to the tool.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 1c46c3982..8ca223763 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -23,19 +23,18 @@
MANDISTPAGES = runtests.1.dist testcurl.1.dist
ED_1 = ftpserver.pl.in httpserver.pl.in secureserver.pl.in runtests.pl.in
-ED_2 = getpart.pm FILEFORMAT.md README stunnel.pem memanalyze.pl.in testcurl.pl.in
+ED_2 = getpart.pm FILEFORMAT.md README.md stunnel.pem memanalyze.pl.in testcurl.pl.in
ED_3 = valgrind.pm ftp.pm sshserver.pl.in sshhelp.pm pathhelp.pm testcurl.1 runtests.1
ED_4 = serverhelp.pm tftpserver.pl.in rtspserver.pl.in directories.pm symbol-scan.pl.in
ED_5 = CMakeLists.txt mem-include-scan.pl.in valgrind.supp extern-scan.pl.in
ED_6 = manpage-scan.pl.in nroff-scan.pl.in http2-server.pl.in dictserver.py.in
-ED_7 = negtelnetserver.py.in smbserver.py.in curl_test_data.py.in
-ED_8 = objnames-test08.sh objnames-test10.sh objnames.inc
-ED_9 = disable-scan.pl.in error-codes.pl.in badsymbols.pl.in
-ED_10 = azure.pm appveyor.pm version-scan.pl.in options-scan.pl
+ED_7 = negtelnetserver.py.in smbserver.py.in util.py.in
+ED_8 = disable-scan.pl.in error-codes.pl.in badsymbols.pl.in
+ED_9 = azure.pm appveyor.pm version-scan.pl.in options-scan.pl
-EXTRA_DIST = $(ED_1) $(ED_2) $(ED_3) $(ED_4) $(ED_5) $(ED_6) $(ED_7) $(ED_8) $(ED_9) $(ED_10)
+EXTRA_DIST = $(ED_1) $(ED_2) $(ED_3) $(ED_4) $(ED_5) $(ED_6) $(ED_7) $(ED_8) $(ED_9)
-check_SCRIPTS = smbserver.py curl_test_data.py negtelnetserver.py dictserver.py
+check_SCRIPTS = smbserver.py util.py negtelnetserver.py dictserver.py
DISTCLEANFILES = configurehelp.pm
@@ -118,9 +117,9 @@ smbserver.py: smbserver.py.in Makefile
$(do_subst) < $(srcdir)/smbserver.py.in > smbserver.py
@chmod +x smbserver.py
-curl_test_data.py: curl_test_data.py.in Makefile
- $(do_subst) < $(srcdir)/curl_test_data.py.in > curl_test_data.py
- @chmod +x curl_test_data.py
+util.py: util.py.in Makefile
+ $(do_subst) < $(srcdir)/util.py.in > util.py
+ @chmod +x util.py
negtelnetserver.py: negtelnetserver.py.in Makefile
$(do_subst) < $(srcdir)/negtelnetserver.py.in > negtelnetserver.py
diff --git a/tests/README b/tests/README.md
index 209887dfc..4b524a045 100644
--- a/tests/README
+++ b/tests/README.md
@@ -1,53 +1,19 @@
- _ _ ____ _
- ___| | | | _ \| |
- / __| | | | |_) | |
- | (__| |_| | _ <| |___
- \___|\___/|_| \_\_____|
-
-The curl Test Suite
-
- 1. Running
- 1.1 Requires to run
- 1.2 Port numbers used by test servers
- 1.3 Test servers
- 1.4 Run
- 1.5 Shell startup scripts
- 1.6 Memory test
- 1.7 Debug
- 1.8 Logs
- 1.9 Test input files
- 1.10 Code coverage
- 1.11 Remote testing
-
- 2. Numbering
- 2.1 Test case numbering
-
- 3. Write tests
- 3.1 test data
- 3.2 curl tests
- 3.3 libcurl tests
- 3.4 unit tests
-
- 4. TODO
- 4.1 More protocols
- 4.2 SOCKS auth
-
-==============================================================================
-
-1. Running
-
- 1.1 Requires to run
-
- perl (and a unix-style shell)
- python (and a unix-style shell, for SMB and TELNET tests)
- python-impacket (for SMB tests)
- diff (when a test fails, a diff is shown)
- stunnel (for HTTPS and FTPS tests)
- OpenSSH or SunSSH (for SCP, SFTP and SOCKS4/5 tests)
- nghttpx (for HTTP/2 tests)
- nroff (for --manual tests)
-
- 1.1.1 Installation of python-impacket
+# The curl Test Suite
+
+# Running
+
+## Requires to run
+
+ - perl (and a unix-style shell)
+ - python (and a unix-style shell, for SMB and TELNET tests)
+ - python-impacket (for SMB tests)
+ - diff (when a test fails, a diff is shown)
+ - stunnel (for HTTPS and FTPS tests)
+ - OpenSSH or SunSSH (for SCP, SFTP and SOCKS4/5 tests)
+ - nghttpx (for HTTP/2 tests)
+ - nroff (for --manual tests)
+
+### Installation of python-impacket
The Python-based test servers support both recent Python 2 and 3.
You can figure out your default Python interpreter with python -V
@@ -56,33 +22,33 @@ The curl Test Suite
You can use pip or your OS' package manager to install 'impacket'.
On Debian/Ubuntu the package names are:
- Python 2: 'python-impacket'
- Python 3: 'python3-impacket'
+
+ - Python 2: 'python-impacket'
+ - Python 3: 'python3-impacket'
On FreeBSD the package names are:
- Python 2: 'py27-impacket'
- Python 3: 'py37-impacket'
+
+ - Python 2: 'py27-impacket'
+ - Python 3: 'py37-impacket'
On any system where pip is available:
- Python 2: 'pip2 install impacket'
- Python 3: 'pip3 install impacket'
+
+ - Python 2: 'pip2 install impacket'
+ - Python 3: 'pip3 install impacket'
You may also need to manually install the Python package 'six'
as that may be a missing requirement for impacket on Python 3.
- 1.2 Port numbers used by test servers
-
- Tests are written to use as few fixed fixed port numbers as possible and all
- tests should be written to use suitable variables instead of port numbers so
- that test cases continue to work independent on what port numbers the test
- servers actually use.
+### Port numbers used by test servers
- The remaining fixed-port test servers that are still used, use the port
- range 8890 - 8904 by default, but can be moved with runtests' -b option.
+ All test servers run on "random" port numbers. All tests should be written
+ to use suitable variables instead of fixed port numbers so that test cases
+ continue to work independent on what port numbers the test servers actually
+ use.
- See the FILEFORMAT for a listing of existing port number variables.
+ See [FILEFORMAT](FILEFORMAT.md) for the port number variables.
- 1.3 Test servers
+### Test servers
The test suite runs simple FTP, POP3, IMAP, SMTP, HTTP and TFTP stand-alone
servers on the ports listed above to which it makes requests. For SSL tests,
@@ -99,27 +65,28 @@ The curl Test Suite
The HTTP server supports listening on a Unix domain socket, the default
location is 'http.sock'.
- 1.4 Run
+### Run
- './configure && make && make test'. This builds the test suite support code
+ `./configure && make && make test`. This builds the test suite support code
and invokes the 'runtests.pl' perl script to run all the tests. Edit the top
variables of that script in case you have some specific needs, or run the
script manually (after the support code has been built).
- The script breaks on the first test that doesn't do OK. Use -a to prevent
- the script from aborting on the first error. Run the script with -v for more
- verbose output. Use -d to run the test servers with debug output enabled as
- well. Specifying -k keeps all the log files generated by the test intact.
-
- Use -s for shorter output, or pass test numbers to run specific tests only
- (like "./runtests.pl 3 4" to test 3 and 4 only). It also supports test case
- ranges with 'to', as in "./runtests 3 to 9" which runs the seven tests from
- 3 to 9. Any test numbers starting with ! are disabled, as are any test
- numbers found in the files data/DISABLED or data/DISABLED.local (one per
+ The script breaks on the first test that doesn't do OK. Use `-a` to prevent
+ the script from aborting on the first error. Run the script with `-v` for
+ more verbose output. Use `-d` to run the test servers with debug output
+ enabled as well. Specifying `-k` keeps all the log files generated by the
+ test intact.
+
+ Use `-s` for shorter output, or pass test numbers to run specific tests only
+ (like `./runtests.pl 3 4` to test 3 and 4 only). It also supports test case
+ ranges with 'to', as in `./runtests.pl 3 to 9` which runs the seven tests
+ from 3 to 9. Any test numbers starting with ! are disabled, as are any test
+ numbers found in the files `data/DISABLED` or `data/DISABLED.local` (one per
line). The latter is meant for local temporary disables and will be ignored
by git.
- When -s is not present, each successful test will display on one line the
+ When `-s` is not present, each successful test will display on one line the
test number and description and on the next line a set of flags, the test
result, current test sequence, total number of tests to be run and an
estimated amount of time to complete the test run. The flags consist of
@@ -134,7 +101,7 @@ The curl Test Suite
m memory
v valgrind
- 1.5 Shell startup scripts
+### Shell startup scripts
Tests which use the ssh test server, SCP/SFTP/SOCKS tests, might be badly
influenced by the output of system wide or user specific shell startup
@@ -150,51 +117,51 @@ The curl Test Suite
output of a shell startup script. Locate, cleanup or adjust the shell
script.
- 1.6 Memory test
+### Memory test
The test script will check that all allocated memory is freed properly IF
- curl has been built with the CURLDEBUG define set. The script will
+ curl has been built with the `CURLDEBUG` define set. The script will
automatically detect if that is the case, and it will use the
'memanalyze.pl' script to analyze the memory debugging output.
Also, if you run tests on a machine where valgrind is found, the script will
- use valgrind to run the test with (unless you use -n) to further verify
+ use valgrind to run the test with (unless you use `-n`) to further verify
correctness.
- runtests.pl's -t option will enable torture testing mode, which runs each
+ runtests.pl's `-t` option will enable torture testing mode, which runs each
test many times and makes each different memory allocation fail on each
successive run. This tests the out of memory error handling code to ensure
that memory leaks do not occur even in those situations. It can help to
- compile curl with CPPFLAGS=-DMEMDEBUG_LOG_SYNC when using this option, to
+ compile curl with `CPPFLAGS=-DMEMDEBUG_LOG_SYNC` when using this option, to
ensure that the memory log file is properly written even if curl crashes.
- 1.7 Debug
+### Debug
If a test case fails, you can conveniently get the script to invoke the
debugger (gdb) for you with the server running and the exact same command
- line parameters that failed. Just invoke 'runtests.pl <test number> -g' and
+ line parameters that failed. Just invoke `runtests.pl <test number> -g` and
then just type 'run' in the debugger to perform the command through the
debugger.
- 1.8 Logs
+### Logs
All logs are generated in the log/ subdirectory (it is emptied first in the
- runtests.pl script). Use runtests.pl -k to force it to keep the temporary
- files after the test run since successful runs will clean it up otherwise.
+ runtests.pl script). They remain in there after a test run.
- 1.9 Test input files
+### Test input files
- All test cases are put in the data/ subdirectory. Each test is stored in the
- file named according to the test number.
+ All test cases are put in the `data/` subdirectory. Each test is stored in
+ the file named according to the test number.
- See FILEFORMAT for the description of the test case files.
+ See [FILEFORMAT.md](FILEFORMAT.md) for a description of the test case file
+ format.
- 1.10 Code coverage
+### Code coverage
- gcc provides a tool that can determine the code coverage figures for
- the test suite. To use it, configure curl with
- CFLAGS='-fprofile-arcs -ftest-coverage -g -O0'. Make sure you run the normal
- and torture tests to get more full coverage, i.e. do:
+ gcc provides a tool that can determine the code coverage figures for the
+ test suite. To use it, configure curl with `CFLAGS='-fprofile-arcs
+ -ftest-coverage -g -O0`. Make sure you run the normal and torture tests to
+ get more full coverage, i.e. do:
make test
make test-torture
@@ -207,7 +174,7 @@ The curl Test Suite
The text mode tool gcov may also be used, but it doesn't handle object files
in more than one directory very well.
- 1.11 Remote testing
+### Remote testing
The runtests.pl script provides some hooks to allow curl to be tested on a
machine where perl can not be run. The test framework in this case runs on
@@ -215,63 +182,48 @@ The curl Test Suite
system using ssh or some other remote execution method. See the comments at
the beginning of runtests.pl for details.
-2. Numbering
-
- 2.1 Test case numbering
+## Test case numbering
- Test cases used to be numbered by category, but the ranges filled
+ Test cases used to be numbered by category ranges, but the ranges filled
up. Subsets of tests can now be selected by passing keywords to the
- runtests.pl script via the make TFLAGS variable.
+ runtests.pl script via the make `TFLAGS` variable.
- New tests should now be added by finding a free number in
- tests/data/Makefile.inc.
+ New tests are added by finding a free number in `tests/data/Makefile.inc`.
-3. Write tests
+## Write tests
Here's a quick description on writing test cases. We basically have three
kinds of tests: the ones that test the curl tool, the ones that build small
applications and test libcurl directly and the unit tests that test
individual (possibly internal) functions.
- 3.1 test data
+### test data
Each test has a master file that controls all the test data. What to read,
what the protocol exchange should look like, what exit code to expect and
what command line arguments to use etc.
- These files are tests/data/test[num] where [num] is described in section 2
- of this document, and the XML-like file format of them is described in the
- separate tests/FILEFORMAT document.
+ These files are `tests/data/test[num]` where `[num]` is just a unique
+ identifier described above, and the XML-like file format of them is
+ described in the separate [FILEFORMAT.md](FILEFORMAT.md) document.
- 3.2 curl tests
+### curl tests
A test case that runs the curl tool and verifies that it gets the correct
data, it sends the correct data, it uses the correct protocol primitives
etc.
- 3.3 libcurl tests
+### libcurl tests
The libcurl tests are identical to the curl ones, except that they use a
specific and dedicated custom-built program to run instead of "curl". This
- tool is built from source code placed in tests/libtest and if you want to
+ tool is built from source code placed in `tests/libtest` and if you want to
make a new libcurl test that is where you add your code.
- 3.4 unit tests
+### unit tests
- Unit tests are tests in the 13xx sequence and they are placed in tests/unit.
- There's a tests/unit/README describing the specific set of checks and macros
- that may be used when writing tests that verify behaviors of specific
- individual functions.
+ Unit tests are placed in `tests/unit`. There's a tests/unit/README
+ describing the specific set of checks and macros that may be used when
+ writing tests that verify behaviors of specific individual functions.
The unit tests depend on curl being built with debug enabled.
-
-4. TODO
-
- 4.1 More protocols
-
- Add tests for TELNET, LDAP, DICT...
-
- 4.2 SOCKS auth
-
- SOCKS4/5 test deficiencies - no proxy authentication tests as SSH (the
- test mechanism) doesn't support them
diff --git a/tests/appveyor.pm b/tests/appveyor.pm
index 64b2ab3ba..bc905c1d6 100644
--- a/tests/appveyor.pm
+++ b/tests/appveyor.pm
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -34,12 +34,12 @@ sub appveyor_check_environment {
}
sub appveyor_create_test_result {
- my ($testnum, $testname)=@_;
+ my ($curl, $testnum, $testname)=@_;
$testname =~ s/\\/\\\\/g;
$testname =~ s/\'/\\\'/g;
$testname =~ s/\"/\\\"/g;
my $appveyor_baseurl="$ENV{'APPVEYOR_API_URL'}";
- my $appveyor_result=`curl --silent --noproxy "*" \\
+ my $appveyor_result=`$curl --silent --noproxy "*" \\
--header "Content-Type: application/json" \\
--data "
{
@@ -55,7 +55,7 @@ sub appveyor_create_test_result {
}
sub appveyor_update_test_result {
- my ($testnum, $error, $start, $stop)=@_;
+ my ($curl, $testnum, $error, $start, $stop)=@_;
my $testname=$APPVEYOR_TEST_NAMES{$testnum};
if(!defined $testname) {
return;
@@ -83,7 +83,7 @@ sub appveyor_update_test_result {
$appveyor_category = 'Error';
}
my $appveyor_baseurl="$ENV{'APPVEYOR_API_URL'}";
- my $appveyor_result=`curl --silent --noproxy "*" --request PUT \\
+ my $appveyor_result=`$curl --silent --noproxy "*" --request PUT \\
--header "Content-Type: application/json" \\
--data "
{
@@ -98,7 +98,7 @@ sub appveyor_update_test_result {
"$appveyor_baseurl/api/tests"`;
print "AppVeyor API result: $appveyor_result\n" if ($appveyor_result);
if($appveyor_category eq 'Error') {
- $appveyor_result=`curl --silent --noproxy "*" \\
+ $appveyor_result=`$curl --silent --noproxy "*" \\
--header "Content-Type: application/json" \\
--data "
{
diff --git a/tests/azure.pm b/tests/azure.pm
index 004c3d309..4f64622b0 100644
--- a/tests/azure.pm
+++ b/tests/azure.pm
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -37,8 +37,9 @@ sub azure_check_environment {
}
sub azure_create_test_run {
+ my ($curl)=@_;
my $azure_baseurl="$ENV{'SYSTEM_TEAMFOUNDATIONCOLLECTIONURI'}$ENV{'SYSTEM_TEAMPROJECTID'}";
- my $azure_run=`curl --silent --noproxy "*" \\
+ my $azure_run=`$curl --silent --noproxy "*" \\
--header "Authorization: Bearer $ENV{'AZURE_ACCESS_TOKEN'}" \\
--header "Content-Type: application/json" \\
--data "
@@ -56,12 +57,13 @@ sub azure_create_test_run {
}
sub azure_create_test_result {
- my ($azure_run_id, $testnum, $testname)=@_;
+ my ($curl, $azure_run_id, $testnum, $testname)=@_;
$testname =~ s/\\/\\\\/g;
$testname =~ s/\'/\\\'/g;
$testname =~ s/\"/\\\"/g;
+ my $title_testnum=sprintf("%04d", $testnum);
my $azure_baseurl="$ENV{'SYSTEM_TEAMFOUNDATIONCOLLECTIONURI'}$ENV{'SYSTEM_TEAMPROJECTID'}";
- my $azure_result=`curl --silent --noproxy "*" \\
+ my $azure_result=`$curl --silent --noproxy "*" \\
--header "Authorization: Bearer $ENV{'AZURE_ACCESS_TOKEN'}" \\
--header "Content-Type: application/json" \\
--data "
@@ -69,7 +71,8 @@ sub azure_create_test_result {
{
'build': {'id': '$ENV{'BUILD_BUILDID'}'},
'testCase': {'id': $testnum},
- 'testCaseTitle': '$testname',
+ 'testCaseTitle': '$title_testnum: $testname',
+ 'testCaseRevision': 2,
'automatedTestName': 'curl.tests.$testnum',
'outcome': 'InProgress'
}
@@ -83,7 +86,7 @@ sub azure_create_test_result {
}
sub azure_update_test_result {
- my ($azure_run_id, $azure_result_id, $testnum, $error, $start, $stop)=@_;
+ my ($curl, $azure_run_id, $azure_result_id, $testnum, $error, $start, $stop)=@_;
if(!defined $stop) {
$stop = $start;
}
@@ -104,7 +107,7 @@ sub azure_update_test_result {
$azure_outcome = 'Failed';
}
my $azure_baseurl="$ENV{'SYSTEM_TEAMFOUNDATIONCOLLECTIONURI'}$ENV{'SYSTEM_TEAMPROJECTID'}";
- my $azure_result=`curl --silent --noproxy "*" --request PATCH \\
+ my $azure_result=`$curl --silent --noproxy "*" --request PATCH \\
--header "Authorization: Bearer $ENV{'AZURE_ACCESS_TOKEN'}" \\
--header "Content-Type: application/json" \\
--data "
@@ -126,9 +129,9 @@ sub azure_update_test_result {
}
sub azure_update_test_run {
- my ($azure_run_id)=@_;
+ my ($curl, $azure_run_id)=@_;
my $azure_baseurl="$ENV{'SYSTEM_TEAMFOUNDATIONCOLLECTIONURI'}$ENV{'SYSTEM_TEAMPROJECTID'}";
- my $azure_run=`curl --silent --noproxy "*" --request PATCH \\
+ my $azure_run=`$curl --silent --noproxy "*" --request PATCH \\
--header "Authorization: Bearer $ENV{'AZURE_ACCESS_TOKEN'}" \\
--header "Content-Type: application/json" \\
--data "
diff --git a/tests/badsymbols.pl.in b/tests/badsymbols.pl.in
index 1ecc4f669..b8077529f 100755
--- a/tests/badsymbols.pl.in
+++ b/tests/badsymbols.pl.in
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/certs/Makefile.am b/tests/certs/Makefile.am
index f5665f7fa..c406417ad 100644
--- a/tests/certs/Makefile.am
+++ b/tests/certs/Makefile.am
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/certs/scripts/Makefile.am b/tests/certs/scripts/Makefile.am
index 271fb0e4f..0f381ee7a 100644
--- a/tests/certs/scripts/Makefile.am
+++ b/tests/certs/scripts/Makefile.am
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/convsrctest.pl.in b/tests/convsrctest.pl.in
index 4061ff3e2..0fca802ba 100755
--- a/tests/convsrctest.pl.in
+++ b/tests/convsrctest.pl.in
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/data/CMakeLists.txt b/tests/data/CMakeLists.txt
index 480dee62d..883d58358 100644
--- a/tests/data/CMakeLists.txt
+++ b/tests/data/CMakeLists.txt
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/data/DISABLED b/tests/data/DISABLED
index eb4407a6b..0d08d33af 100644
--- a/tests/data/DISABLED
+++ b/tests/data/DISABLED
@@ -2,31 +2,27 @@
# test cases are run by runtests.pl. Just add the plain test case numbers, one
# per line.
# Lines starting with '#' letters are treated as comments.
+#
+# Uses SRP to "a server not supporting it" but modern stunnel versions
+# will silently accept it and remain happy
+323
+#
594
+836
+882
+938
1209
1211
+# fnmatch differences are just too common to make testing them sensible
+1307
1316
+# test 1510 causes problems on the CI on github
+# example: https://travis-ci.org/curl/curl/builds/81633600
+1510
1512
-836
-882
-938
# test 1801 causes problems on Mac OS X and github
# https://github.com/curl/curl/issues/380
1801
-# test 1510 causes problems on the CI on github
-# example: https://travis-ci.org/curl/curl/builds/81633600
-1510
-# Pipelining test that is causing false positives a little too often
-1903
-# fnmatch differences are just too common to make testing them sensible
-1307
-# Pipelining is deprecated
-530
-584
-1900
-1901
-1902
-2033
# Unused in gnurl
1173
# Skip in gnurl until we fix the manpages->mdocml
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index 24e8529a9..bfffb822c 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index b92cd2df6..0a0d27bfd 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -58,7 +58,7 @@ test307 test308 test309 test310 test311 test312 test313 test314 test315 \
test316 test317 test318 test319 test320 test321 test322 test323 test324 \
test325 test326 test327 test328 test329 test330 test331 test332 test333 \
test334 test335 test336 test337 test338 test339 test340 test341 test342 \
-test343 test344 test345 test346 \
+test343 test344 test345 test346 test347 test348 \
test350 test351 test352 test353 test354 test355 test356 test357 test358 \
test359 \
test393 test394 test395 test396 test397 \
@@ -66,20 +66,20 @@ test393 test394 test395 test396 test397 \
test400 test401 test402 test403 test404 test405 test406 test407 test408 \
test409 \
\
-test430 test431 test432 \
+test430 test431 test432 test433 test434 \
\
-test490 test491 test492 \
+test490 test491 test492 test493 \
\
test500 test501 test502 test503 test504 test505 test506 test507 test508 \
test509 test510 test511 test512 test513 test514 test515 test516 test517 \
test518 test519 test520 test521 test522 test523 test524 test525 test526 \
-test527 test528 test529 test530 test531 test532 test533 test534 test535 \
+test527 test528 test529 test531 test532 test533 test534 test535 \
test537 test538 test539 test540 test541 test542 test543 test544 \
test545 test546 test547 test548 test549 test550 test551 test552 test553 \
test554 test555 test556 test557 test558 test559 test560 test561 test562 \
test563 test564 test565 test566 test567 test568 test569 test570 test571 \
test572 test573 test574 test575 test576 test577 test578 test579 test580 \
-test581 test582 test583 test584 test585 test586 test587 test588 test589 \
+test581 test582 test583 test585 test586 test587 test588 test589 \
test590 test591 test592 test593 test594 test595 test596 test597 test598 \
test599 test600 test601 test602 test603 test604 test605 test606 test607 \
test608 test609 test610 test611 test612 test613 test614 test615 test616 \
@@ -136,56 +136,52 @@ test1136 test1137 test1138 test1141 test1142 test1143 \
test1144 test1145 test1146 test1147 test1148 test1149 test1150 test1151 \
test1152 test1153 test1154 test1155 test1156 test1157 test1158 test1159 \
test1160 test1161 test1162 test1163 test1164 test1165 test1166 test1167 \
-test1168 \
-\
-test1170 test1171 test1172 test1173 test1174 test1175 test1176 test1177 \
-test1178 test1179 \
+test1168 test1170 test1171 test1172 test1173 test1174 test1175 \
+test1176 test1177 test1178 test1179 \
\
test1190 test1191 test1192 test1193 test1194 test1195 test1196 test1197 \
\
test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 \
test1208 test1209 test1210 test1211 test1212 test1213 test1214 test1215 \
-test1216 test1217 test1218 test1219 \
-test1220 test1221 test1222 test1223 test1224 test1225 test1226 test1227 \
-test1228 test1229 test1230 test1231 test1232 test1233 test1234 test1235 \
-test1236 test1237 test1238 test1239 test1240 test1241 test1242 test1243 \
-test1244 test1245 test1246 test1247 test1248 test1249 test1250 test1251 \
-test1252 test1253 test1254 test1255 test1256 test1257 test1258 test1259 \
-test1260 test1261 test1262 test1263 test1264 test1265 test1266 test1267 \
-test1268 test1269 test1270 test1271 \
+test1216 test1217 test1218 test1219 test1220 test1223 \
+test1224 test1225 test1226 test1227 test1228 test1229 test1230 test1231 \
+test1232 test1233 test1234 test1235 test1236 test1237 test1238 test1239 \
+test1240 test1241 test1242 test1243 test1244 test1245 test1246 test1247 \
+test1248 test1249 test1250 test1251 test1252 test1253 test1254 test1255 \
+test1256 test1257 test1258 test1259 test1260 test1261 test1262 test1263 \
+test1264 test1265 test1266 test1267 test1268 test1269 test1270 test1271 \
\
test1280 test1281 test1282 test1283 test1284 test1285 test1286 test1287 \
test1288 test1289 test1290 test1291 test1292 test1293 test1294 test1295 \
-test1296 \
-\
-test1298 test1299 test1300 test1301 test1302 test1303 test1304 test1305 \
-test1306 test1307 test1308 test1309 test1310 test1311 test1312 test1313 \
-test1314 test1315 test1316 test1317 test1318 test1319 test1320 test1321 \
-test1322 test1323 test1324 test1325 test1326 test1327 test1328 test1329 \
-test1330 test1331 test1332 test1333 test1334 test1335 test1336 test1337 \
-test1338 test1339 test1340 test1341 test1342 test1343 test1344 test1345 \
-test1346 test1347 test1348 test1349 test1350 test1351 test1352 test1353 \
-test1354 test1355 test1356 test1357 test1358 test1359 test1360 test1361 \
-test1362 test1363 test1364 test1365 test1366 test1367 test1368 test1369 \
-test1370 test1371 test1372 test1373 test1374 test1375 test1376 test1377 \
-test1378 test1379 test1380 test1381 test1382 test1383 test1384 test1385 \
-test1386 test1387 test1388 test1389 test1390 test1391 test1392 test1393 \
-test1394 test1395 test1396 test1397 test1398 test1399 test1400 test1401 \
-test1402 test1403 test1404 test1405 test1406 test1407 test1408 test1409 \
-test1410 test1411 test1412 test1413 test1414 test1415 test1416 test1417 \
-test1418 test1419 test1420 test1421 test1422 test1423 test1424 test1425 \
-test1426 test1427 test1428 test1429 test1430 test1431 test1432 test1433 \
-test1434 test1435 test1436 test1437 test1438 test1439 test1440 test1441 \
-test1442 test1443 test1444 test1445 test1446 test1447 test1448 test1449 \
-test1450 test1451 test1452 test1453 test1454 test1455 test1456 test1457 \
-test1458 test1459 test1460 \
+test1296 test1297 test1298 test1299 test1300 test1301 test1302 test1303 \
+test1304 test1305 test1306 test1307 test1308 test1309 test1310 test1311 \
+test1312 test1313 test1314 test1315 test1316 test1317 test1318 test1319 \
+test1320 test1321 test1322 test1323 test1324 test1325 test1326 test1327 \
+test1328 test1329 test1330 test1331 test1332 test1333 test1334 test1335 \
+test1336 test1337 test1338 test1339 test1340 test1341 test1342 test1343 \
+test1344 test1345 test1346 test1347 test1348 test1349 test1350 test1351 \
+test1352 test1353 test1354 test1355 test1356 test1357 test1358 test1359 \
+test1360 test1361 test1362 test1363 test1364 test1365 test1366 test1367 \
+test1368 test1369 test1370 test1371 test1372 test1373 test1374 test1375 \
+test1376 test1377 test1378 test1379 test1380 test1381 test1382 test1383 \
+test1384 test1385 test1386 test1387 test1388 test1389 test1390 test1391 \
+test1392 test1393 test1394 test1395 test1396 test1397 test1398 test1399 \
+test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 \
+test1408 test1409 test1410 test1411 test1412 test1413 test1414 test1415 \
+test1416 test1417 test1418 test1419 test1420 test1421 test1422 test1423 \
+test1424 test1425 test1426 test1427 test1428 test1429 test1430 test1431 \
+test1432 test1433 test1434 test1435 test1436 test1437 test1438 test1439 \
+test1440 test1441 test1442 test1443 test1444 test1445 test1446 test1447 \
+test1448 test1449 test1450 test1451 test1452 test1453 test1454 test1455 \
+test1456 test1457 test1458 test1459 test1460 test1461 test1462 test1463 \
+test1464 test1465 \
\
test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \
test1508 test1509 test1510 test1511 test1512 test1513 test1514 test1515 \
test1516 test1517 test1518 test1519 test1520 test1521 test1522 test1523 \
test1524 test1525 test1526 test1527 test1528 test1529 test1530 test1531 \
test1532 test1533 test1534 test1535 test1536 test1537 test1538 test1539 \
-test1540 test1541 \
+test1540 \
\
test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 \
test1558 test1559 test1560 test1561 test1562 test1563 test1564 test1565 \
@@ -201,19 +197,20 @@ test1620 test1621 \
test1630 test1631 test1632 test1633 \
\
test1650 test1651 test1652 test1653 test1654 test1655 \
+test1660 \
\
test1700 test1701 test1702 \
\
test1800 test1801 \
\
-test1900 test1901 test1902 test1903 test1904 test1905 test1906 test1907 \
-test1908 test1909 test1910 \
+ test1904 test1905 test1906 test1907 \
+test1908 test1909 test1910 test1911 test1912 test1913 test1914 test1915 \
\
test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
test2008 test2009 test2010 test2011 test2012 test2013 test2014 test2015 \
test2016 test2017 test2018 test2019 test2020 test2021 test2022 test2023 \
test2024 test2025 test2026 test2027 test2028 test2029 test2030 test2031 \
-test2032 test2033 test2034 test2035 test2036 test2037 test2038 test2039 \
+test2032 test2034 test2035 test2036 test2037 test2038 test2039 \
test2040 test2041 test2042 test2043 test2044 test2045 test2046 test2047 \
test2048 test2049 test2050 test2051 test2052 test2053 test2054 test2055 \
test2056 test2057 test2058 test2059 test2060 test2061 test2062 test2063 \
@@ -224,5 +221,5 @@ test2078 \
test2080 \
test2100 \
\
-test3000 test3001 \
-test3002 test3003 test3004 test3005 test3006 test3007 test3010
+test3000 test3001 test3002 test3003 test3004 test3005 test3006 test3007 \
+test3008 test3009 test3010 test3011 test3012 test3013 test3014 test3015
diff --git a/tests/data/test1 b/tests/data/test1
index 7c0e1602a..461375b62 100644
--- a/tests/data/test1
+++ b/tests/data/test1
@@ -42,12 +42,10 @@ http://%HOSTIP:%HTTPPORT/1
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test10 b/tests/data/test10
index 806aa697f..c5053b5db 100644
--- a/tests/data/test10
+++ b/tests/data/test10
@@ -43,12 +43,10 @@ the
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /we/want/10 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 78
Expect: 100-continue
diff --git a/tests/data/test1001 b/tests/data/test1001
index 53d7da381..6edaade79 100644
--- a/tests/data/test1001
+++ b/tests/data/test1001
@@ -81,14 +81,11 @@ test
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://%HOSTIP:%HTTPPORT/1001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Content-Range: bytes 2-4/5
-User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 0
@@ -97,6 +94,7 @@ GET http://%HOSTIP:%HTTPPORT/1001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="auser", realm="testrealm", nonce="1053604144", uri="/1001", response="6af4d89c952f4dd4cc215a6878dc499d"
Content-Range: bytes 2-4/5
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 3
diff --git a/tests/data/test1002 b/tests/data/test1002
index 5b6ef9431..7ec7501f7 100644
--- a/tests/data/test1002
+++ b/tests/data/test1002
@@ -80,14 +80,11 @@ test
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://%HOSTIP:%HTTPPORT/1002.upload1 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Content-Range: bytes 2-4/5
-User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 0
@@ -96,6 +93,7 @@ GET http://%HOSTIP:%HTTPPORT/1002.upload1 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="auser", realm="testrealm", nonce="1053604144", uri="/1002.upload1", response="198aa9b6acb4b0c71d02a197a5e41f54"
Content-Range: bytes 2-4/5
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 3
@@ -105,7 +103,7 @@ st
GET http://%HOSTIP:%HTTPPORT/1002.upload2 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Content-Range: bytes 2-4/5
-User-Agent: curl/7.16.1
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 0
@@ -114,7 +112,7 @@ GET http://%HOSTIP:%HTTPPORT/1002.upload2 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="auser", realm="testrealm", nonce="1053604144", uri="/1002.upload2", response="d711f0d2042786d930de635ba0d1a1d0"
Content-Range: bytes 2-4/5
-User-Agent: curl/7.16.1
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 3
diff --git a/tests/data/test1004 b/tests/data/test1004
index 955163b36..05e92a598 100644
--- a/tests/data/test1004
+++ b/tests/data/test1004
@@ -43,12 +43,10 @@ http://%HOSTIP:%HTTPPORT/1004 --proxy ""
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1004 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1008 b/tests/data/test1008
index a1ef0dd7a..a076fa0d4 100644
--- a/tests/data/test1008
+++ b/tests/data/test1008
@@ -110,23 +110,22 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
CONNECT test.remote.example.com.1008:%HTTPPORT HTTP/1.1
Host: test.remote.example.com.1008:%HTTPPORT
Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
CONNECT test.remote.example.com.1008:%HTTPPORT HTTP/1.1
Host: test.remote.example.com.1008:%HTTPPORT
Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAADj3hs3u3j0kgJqCrLM+74BmaoNHDfIJjHRlc3R1c2VyY3VybGhvc3Q=
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
GET /path/10080002 HTTP/1.1
-User-Agent: curl/7.12.3-CVS (i686-pc-linux-gnu) libcurl/7.12.3-CVS OpenSSL/0.9.6b zlib/1.1.4
Host: test.remote.example.com.1008:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
[DISCONNECT]
diff --git a/tests/data/test1011 b/tests/data/test1011
index 566867dd6..6d3297a76 100644
--- a/tests/data/test1011
+++ b/tests/data/test1011
@@ -56,19 +56,17 @@ http://%HOSTIP:%HTTPPORT/blah/1011 -L -d "moo"
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
POST /blah/1011 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 3
Content-Type: application/x-www-form-urlencoded
mooGET /blah/moo.html&testcase=/10110002 HTTP/1.1
-User-Agent: curl/7.10 (i686-pc-linux-gnu) libcurl/7.10 OpenSSL/0.9.6c ipv6 zlib/1.1.3
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1012 b/tests/data/test1012
index 4edc1731e..943db91c0 100644
--- a/tests/data/test1012
+++ b/tests/data/test1012
@@ -56,19 +56,17 @@ http://%HOSTIP:%HTTPPORT/blah/1012 -L -d "moo" --post301
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /blah/1012 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 3
Content-Type: application/x-www-form-urlencoded
mooPOST /blah/moo.html&testcase=/10120002 HTTP/1.1
-User-Agent: curl/7.10 (i686-pc-linux-gnu) libcurl/7.10 OpenSSL/0.9.6c ipv6 zlib/1.1.3
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 3
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test1015 b/tests/data/test1015
index a2b2cefa1..c568b8678 100644
--- a/tests/data/test1015
+++ b/tests/data/test1015
@@ -38,13 +38,10 @@ content to _?!#$'|<>
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /1015 HTTP/1.1
-User-Agent: curl/7.17.2-CVS (i686-pc-linux-gnu) libcurl/7.17.2-CVS OpenSSL/0.9.8g zlib/1.2.3.3 c-ares/1.5.2-CVS libidn/1.1 libssh2/0.19.0-C
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 133
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test1021 b/tests/data/test1021
index 84d1e62a7..10a0314ad 100644
--- a/tests/data/test1021
+++ b/tests/data/test1021
@@ -115,27 +115,27 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
CONNECT test.remote.example.com.1021:%HTTPPORT HTTP/1.1
Host: test.remote.example.com.1021:%HTTPPORT
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
CONNECT test.remote.example.com.1021:%HTTPPORT HTTP/1.1
Host: test.remote.example.com.1021:%HTTPPORT
Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
CONNECT test.remote.example.com.1021:%HTTPPORT HTTP/1.1
Host: test.remote.example.com.1021:%HTTPPORT
Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAADj3hs3u3j0kgJqCrLM+74BmaoNHDfIJjHRlc3R1c2VyY3VybGhvc3Q=
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
GET /path/10210002 HTTP/1.1
-User-Agent: curl/7.12.3-CVS (i686-pc-linux-gnu) libcurl/7.12.3-CVS OpenSSL/0.9.6b zlib/1.1.4
Host: test.remote.example.com.1021:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1024 b/tests/data/test1024
index 086ef267a..4971eedbd 100644
--- a/tests/data/test1024
+++ b/tests/data/test1024
@@ -81,20 +81,20 @@ http://%HOSTIP:%HTTPPORT/want/1024 -L -c log/jar1024
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/1024 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /data/10240002.txt HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /want/10240003.txt HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Cookie: firstcookie=want
diff --git a/tests/data/test1025 b/tests/data/test1025
index 494f8f8d5..66f7532b4 100644
--- a/tests/data/test1025
+++ b/tests/data/test1025
@@ -81,22 +81,22 @@ http://%HOSTIP:%HTTPPORT/want/1025 -L -c log/jar1025 -b forcedcookie=yes
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/1025 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Cookie: forcedcookie=yes
GET /data/10250002.txt HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Cookie: forcedcookie=yes
GET /want/10250003.txt HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Cookie: firstcookie=want; forcedcookie=yes
diff --git a/tests/data/test1028 b/tests/data/test1028
index b154372af..c10d58126 100644
--- a/tests/data/test1028
+++ b/tests/data/test1028
@@ -52,12 +52,10 @@ http://%HOSTIP:%HTTPPORT/10280001 -L
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /10280001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
USER anonymous
diff --git a/tests/data/test1029 b/tests/data/test1029
index c77209cad..9a351a4f3 100644
--- a/tests/data/test1029
+++ b/tests/data/test1029
@@ -36,12 +36,10 @@ http://%HOSTIP:%HTTPPORT/we/want/our/1029 -w '%{redirect_url}\n'
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/our/1029 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1030 b/tests/data/test1030
index 5a8ed4cd6..735c08b7a 100644
--- a/tests/data/test1030
+++ b/tests/data/test1030
@@ -79,12 +79,10 @@ four is the number of lines
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /1030 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 85
Expect: 100-continue
@@ -96,7 +94,7 @@ four is the number of lines
PUT /1030 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="gimme all yer s3cr3ts", nonce="11223344", uri="/1030", response="01cb59db1ddaac246b072d5f5f0716d9"
-User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 85
Expect: 100-continue
diff --git a/tests/data/test1031 b/tests/data/test1031
index 9cfbab5c5..b12785a0c 100644
--- a/tests/data/test1031
+++ b/tests/data/test1031
@@ -59,16 +59,15 @@ http://%HOSTIP:%HTTPPORT/want/this/1031 -L
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/this/1031 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /want/this/1031?coolsite=yes/10310002.txt HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1032 b/tests/data/test1032
index b0b6834cc..0c38ae132 100644
--- a/tests/data/test1032
+++ b/tests/data/test1032
@@ -42,13 +42,11 @@ HTTP HEAD with --range
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
HEAD /1032 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Range: bytes=1-3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1033 b/tests/data/test1033
index 9ad5d2526..908dd32c0 100644
--- a/tests/data/test1033
+++ b/tests/data/test1033
@@ -47,12 +47,10 @@ http://%HOSTIP:%HTTPPORT/1033
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1033 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1035 b/tests/data/test1035
index 62f9d7ae8..b67eab281 100644
--- a/tests/data/test1035
+++ b/tests/data/test1035
@@ -42,9 +42,6 @@ http://too-long-IDN-name-cürl-rüles-la-la-la-dee-da-flooby-nooby.local/page/10
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<errorcode>
3
</errorcode>
diff --git a/tests/data/test1040 b/tests/data/test1040
index e21ed8199..d480bb448 100644
--- a/tests/data/test1040
+++ b/tests/data/test1040
@@ -65,13 +65,11 @@ http://%HOSTIP:%HTTPPORT/1040 -C -
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1040 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Range: bytes=100-
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1041 b/tests/data/test1041
index c77d616a8..4797cf937 100644
--- a/tests/data/test1041
+++ b/tests/data/test1041
@@ -50,15 +50,13 @@ http://%HOSTIP:%HTTPPORT/1041 -Tlog/test1041.txt -C -
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
# curl doesn't do a HEAD request on the remote file so it has no idea whether
# it can skip part of the file or not. Instead, it sends the entire file.
<protocol>
PUT /1041 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Content-Range: bytes 0-99/100
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 100
Expect: 100-continue
diff --git a/tests/data/test1042 b/tests/data/test1042
index dfebaa152..d374d2ab5 100644
--- a/tests/data/test1042
+++ b/tests/data/test1042
@@ -80,13 +80,11 @@ http://%HOSTIP:%HTTPPORT/1042 -C 200
<errorcode>
33
</errorcode>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1042 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Range: bytes=200-
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1043 b/tests/data/test1043
index 4ab498762..e200b61ea 100644
--- a/tests/data/test1043
+++ b/tests/data/test1043
@@ -70,13 +70,11 @@ http://%HOSTIP:%HTTPPORT/1043 -C -
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1043 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Range: bytes=40-
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1045 b/tests/data/test1045
index fa8ad4b44..9de169bab 100644
--- a/tests/data/test1045
+++ b/tests/data/test1045
@@ -39,12 +39,10 @@ http://%HOSTIP:%HTTPPORT/1045 --interface %CLIENTIP
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1045 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1046 b/tests/data/test1046
index e86e1329c..0f04b8a33 100644
--- a/tests/data/test1046
+++ b/tests/data/test1046
@@ -47,12 +47,10 @@ perl -e "print 'Test requires default test client host address' if ( '%CLIENT6IP
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1046 HTTP/1.1
Host: %HOST6IP:%HTTP6PORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1051 b/tests/data/test1051
index 080e1d1d5..7a8eae1bd 100644
--- a/tests/data/test1051
+++ b/tests/data/test1051
@@ -73,9 +73,6 @@ the
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
# The primary reason libcurl sends the data part twice in this test is that
# the test HTTP server is blocking until it has read the entire request,
@@ -85,6 +82,7 @@ the
<protocol>
PUT /want/1051 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 78
Expect: 100-continue
@@ -100,6 +98,7 @@ the
feature
PUT /want/data/10510002.txt?coolsite=yes HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 78
Expect: 100-continue
diff --git a/tests/data/test1052 b/tests/data/test1052
index 10c16b4a7..e0c2f32a6 100644
--- a/tests/data/test1052
+++ b/tests/data/test1052
@@ -69,9 +69,6 @@ the
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
# The primary reason libcurl sends the data part twice in this test is that
# the test HTTP server is blocking until it has read the entire request,
@@ -80,6 +77,7 @@ the
<protocol>
PUT /want/1052 HTTP/1.0
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 78
@@ -94,6 +92,7 @@ the
feature
PUT /want/data/10520002.txt?coolsite=yes HTTP/1.0
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 78
diff --git a/tests/data/test1053 b/tests/data/test1053
index 239a1100f..5f3ec2932 100644
--- a/tests/data/test1053
+++ b/tests/data/test1053
@@ -71,12 +71,12 @@ bar
# Verify data after the test has been "shot"
<verify>
<strip>
-^(User-Agent:|Content-Type: multipart/form-data;|------------).*
+^(Content-Type: multipart/form-data;|------------).*
</strip>
<protocol>
POST /we/want/1053 HTTP/1.1
-User-Agent: curl/7.18.2 (i686-pc-linux-gnu) libcurl/7.18.2 OpenSSL/0.9.7a ipv6 zlib/1.1.4
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 410
Content-Type: multipart/form-data; boundary=----------------------------9ef8d6205763
@@ -99,8 +99,8 @@ bar
------------------------------9ef8d6205763--
POST /we/want/data/10530002.txt?coolsite=yes HTTP/1.1
-User-Agent: curl/7.18.2 (i686-pc-linux-gnu) libcurl/7.18.2 OpenSSL/0.9.7a ipv6 zlib/1.1.4
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 410
Content-Type: multipart/form-data; boundary=----------------------------9ef8d6205763
diff --git a/tests/data/test1054 b/tests/data/test1054
index 54d023267..ac6671f6e 100644
--- a/tests/data/test1054
+++ b/tests/data/test1054
@@ -58,18 +58,17 @@ http://%HOSTIP:%HTTPPORT/blah/1054 -L -d @log/test1054.txt --post301
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /blah/1054 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 10
Content-Type: application/x-www-form-urlencoded
field=dataPOST /blah/moo/testcase/10540002 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 10
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test1055 b/tests/data/test1055
index f25db8f42..4788ae77d 100644
--- a/tests/data/test1055
+++ b/tests/data/test1055
@@ -54,12 +54,10 @@ the
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /1055 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 78
Expect: 100-continue
diff --git a/tests/data/test1056 b/tests/data/test1056
index 756d0f27f..7ccdb2199 100644
--- a/tests/data/test1056
+++ b/tests/data/test1056
@@ -60,16 +60,15 @@ http://%HOSTIP:%HTTPPORT/we/are/all/twits/1056 -L
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/are/all/twits/1056 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /moo/10560002 HTTP/1.1
Host: %HOST6IP:%HTTP6PORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1058 b/tests/data/test1058
index 4eb34da73..d177b5fd7 100644
--- a/tests/data/test1058
+++ b/tests/data/test1058
@@ -39,13 +39,11 @@ http://%HOSTIP:%HTTPPORT/want/1058 -r -101
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/1058 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Range: bytes=-101
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1059 b/tests/data/test1059
index 615e625c9..32e5aec3a 100644
--- a/tests/data/test1059
+++ b/tests/data/test1059
@@ -46,12 +46,10 @@ ftp://test-number:1059/wanted/page -p -x %HOSTIP:%HTTPPORT
<errorcode>
56
</errorcode>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
CONNECT test-number:1059 HTTP/1.1
Host: test-number:1059
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
</protocol>
diff --git a/tests/data/test1060 b/tests/data/test1060
index c4b264c10..889a39054 100644
--- a/tests/data/test1060
+++ b/tests/data/test1060
@@ -18,7 +18,7 @@ HTTP proxy Digest auth
HTTP/1.1 407 Authorization Required to proxy me my dear
Proxy-Authenticate: Digest realm="weirdorealm", nonce="12345"
Content-Length: 40000
-X-tra-long-header: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+X-tra-long-header: %repeat[16080 x a]%
And you should ignore this data. aaaaaaaaaaaaaaaa
And you should ignore this data. aaaaaaaaaaaaaaaa
@@ -845,7 +845,7 @@ Server: no
HTTP/1.1 407 Authorization Required to proxy me my dear
Proxy-Authenticate: Digest realm="weirdorealm", nonce="12345"
Content-Length: 40000
-X-tra-long-header: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+X-tra-long-header: %repeat[16080 x a]%
HTTP/1.1 200 OK swsbounce
Server: no
@@ -881,21 +881,21 @@ http://test.remote.haxx.se.1060:8990/path/10600002 --proxy http://%HOSTIP:%HTTPP
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
CONNECT test.remote.haxx.se.1060:8990 HTTP/1.1
Host: test.remote.haxx.se.1060:8990
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
CONNECT test.remote.haxx.se.1060:8990 HTTP/1.1
Host: test.remote.haxx.se.1060:8990
Proxy-Authorization: Digest username="silly", realm="weirdorealm", nonce="12345", uri="test.remote.haxx.se.1060:8990", response="e1fbed39c26f4efe284adc0e576ff638"
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
GET /path/10600002 HTTP/1.1
Host: test.remote.haxx.se.1060:8990
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1061 b/tests/data/test1061
index 6ddddfee2..1c1c3b1de 100644
--- a/tests/data/test1061
+++ b/tests/data/test1061
@@ -19,7 +19,7 @@ HTTP proxy Digest auth
HTTP/1.1 407 Authorization Required to proxy me my dear
Proxy-Authenticate: Digest realm="weirdorealm", nonce="12345"
Transfer-Encoding: chunked
-X-tra-long-header: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+X-tra-long-header: %repeat[16080 x a]%
9c40
And you should ignore this data. aaaaaaaaaaaaaaaa
@@ -850,7 +850,7 @@ Server: no
HTTP/1.1 407 Authorization Required to proxy me my dear
Proxy-Authenticate: Digest realm="weirdorealm", nonce="12345"
Transfer-Encoding: chunked
-X-tra-long-header: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+X-tra-long-header: %repeat[16080 x a]%
HTTP/1.1 200 OK swsbounce
Server: no
@@ -886,21 +886,21 @@ http://test.remote.haxx.se.1061:8990/path/10610002 --proxy http://%HOSTIP:%HTTPP
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
CONNECT test.remote.haxx.se.1061:8990 HTTP/1.1
Host: test.remote.haxx.se.1061:8990
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
CONNECT test.remote.haxx.se.1061:8990 HTTP/1.1
Host: test.remote.haxx.se.1061:8990
Proxy-Authorization: Digest username="silly", realm="weirdorealm", nonce="12345", uri="test.remote.haxx.se.1061:8990", response="4e23449fa93224834299e7282a70472c"
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
GET /path/10610002 HTTP/1.1
Host: test.remote.haxx.se.1061:8990
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1064 b/tests/data/test1064
index dd05ddf3a..3d2f4d2cb 100644
--- a/tests/data/test1064
+++ b/tests/data/test1064
@@ -44,18 +44,17 @@ test
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /1064.upload1 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 5
test
PUT /10640002.upload2 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 5
diff --git a/tests/data/test1065 b/tests/data/test1065
index 5688ff964..1d27ffb4b 100644
--- a/tests/data/test1065
+++ b/tests/data/test1065
@@ -45,18 +45,17 @@ test
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /1065.upload1 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 5
test
GET /10650002.url2 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1066 b/tests/data/test1066
index bacedefbb..8175af172 100644
--- a/tests/data/test1066
+++ b/tests/data/test1066
@@ -41,16 +41,15 @@ http://%HOSTIP:%HTTPPORT/want/1066 http://%HOSTIP:%HTTPPORT/want/10660001 --dump
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/1066 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /want/10660001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1067 b/tests/data/test1067
index 9fc7a6fa4..4706a0a58 100644
--- a/tests/data/test1067
+++ b/tests/data/test1067
@@ -59,17 +59,16 @@ http://%HOSTIP:%HTTPPORT/want/1067 -L --referer "firstone.html;auto"
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/1067 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Referer: firstone.html
GET /want/data/10670002.txt?coolsite=yes HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Referer: http://%HOSTIP:%HTTPPORT/want/1067
diff --git a/tests/data/test1068 b/tests/data/test1068
index f9bfec90f..15a702d11 100644
--- a/tests/data/test1068
+++ b/tests/data/test1068
@@ -38,12 +38,10 @@ more than one byte
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /bzz/1068 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Transfer-Encoding: chunked
Expect: 100-continue
diff --git a/tests/data/test1070 b/tests/data/test1070
index 81b473de4..6056e5d93 100644
--- a/tests/data/test1070
+++ b/tests/data/test1070
@@ -48,12 +48,10 @@ OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /1070 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Expect: 100-continue
Content-Length: 2313
diff --git a/tests/data/test1071 b/tests/data/test1071
index 4352e6111..d89b74bd0 100644
--- a/tests/data/test1071
+++ b/tests/data/test1071
@@ -85,12 +85,10 @@ four is the number of lines
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /1071 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 85
Expect: 100-continue
@@ -102,6 +100,7 @@ four is the number of lines
PUT /1071 HTTP/1.0
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="gimme all yer s3cr3ts", nonce="11223344", uri="/1071", response="df4cef6b52a30e65d472dd848d2055a1"
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 85
diff --git a/tests/data/test1072 b/tests/data/test1072
index 14b6d804c..128f0944c 100644
--- a/tests/data/test1072
+++ b/tests/data/test1072
@@ -55,12 +55,10 @@ which is impossible in HTTP/1.0
<errorcode>
25
</errorcode>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /1072 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Transfer-Encoding: chunked
Expect: 100-continue
diff --git a/tests/data/test1073 b/tests/data/test1073
index 481f9098f..80f5ec0dc 100644
--- a/tests/data/test1073
+++ b/tests/data/test1073
@@ -49,12 +49,10 @@ which is impossible in HTTP/1.0
<errorcode>
25
</errorcode>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /1073 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Transfer-Encoding: chunked
Expect: 100-continue
diff --git a/tests/data/test1074 b/tests/data/test1074
index 3464b4183..840d46195 100644
--- a/tests/data/test1074
+++ b/tests/data/test1074
@@ -59,16 +59,15 @@ Connection: close
surprise2
</stdout>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/1074 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /wantmore/10740001 HTTP/1.0
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1075 b/tests/data/test1075
index 4b30c593a..f0f255ab6 100644
--- a/tests/data/test1075
+++ b/tests/data/test1075
@@ -64,12 +64,10 @@ four is the number of lines
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /1075 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 85
Expect: 100-continue
@@ -81,6 +79,7 @@ four is the number of lines
PUT /1075 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Basic dGVzdHVzZXI6dGVzdHBhc3M=
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 85
Expect: 100-continue
diff --git a/tests/data/test1076 b/tests/data/test1076
index ad079eb94..8322be23a 100644
--- a/tests/data/test1076
+++ b/tests/data/test1076
@@ -56,19 +56,17 @@ http://%HOSTIP:%HTTPPORT/blah/1076 -L -d "moo" --post302
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /blah/1076 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 3
Content-Type: application/x-www-form-urlencoded
mooPOST /blah/moo.html&testcase=/10760002 HTTP/1.1
-User-Agent: curl/7.10 (i686-pc-linux-gnu) libcurl/7.10 OpenSSL/0.9.6c ipv6 zlib/1.1.3
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 3
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test1077 b/tests/data/test1077
index e917e8a56..8b1d288de 100644
--- a/tests/data/test1077
+++ b/tests/data/test1077
@@ -57,17 +57,16 @@ FTP over HTTP proxy with downgrade to HTTP 1.0
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET ftp://%HOSTIP:%HTTPPORT/we/want/that/page/1077 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET ftp://%HOSTIP:%HTTPPORT/we/want/that/page/10770002 HTTP/1.0
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1078 b/tests/data/test1078
index d705dbca4..65c77ed7c 100644
--- a/tests/data/test1078
+++ b/tests/data/test1078
@@ -53,22 +53,22 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<proxy>
CONNECT %HOSTIP.1078:%HTTPPORT HTTP/1.0
Host: %HOSTIP.1078:%HTTPPORT
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
</proxy>
<protocol>
GET /we/want/that/page/1078 HTTP/1.1
Host: %HOSTIP.1078:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /we/want/that/page/1078 HTTP/1.0
Host: %HOSTIP.1078:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1079 b/tests/data/test1079
index ac7b899fb..460439d53 100644
--- a/tests/data/test1079
+++ b/tests/data/test1079
@@ -58,17 +58,16 @@ http://%HOSTIP:%HTTPPORT/1079 -u testuser:testpass --digest
<errorcode>
52
</errorcode>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1079 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /1079 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="testrealm", nonce="1053604145", uri="/1079", response="e340c7cdca0950462070f46ee139e9f7"
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1080 b/tests/data/test1080
index e0f7d62ae..9fa48576d 100644
--- a/tests/data/test1080
+++ b/tests/data/test1080
@@ -36,16 +36,15 @@ http://%HOSTIP:%HTTPPORT/we/want/our/1080 http://%HOSTIP:%HTTPPORT/we/want/our/1
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/our/1080 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /we/want/our/1080 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1081 b/tests/data/test1081
index d9f895fd2..2a5a765e6 100644
--- a/tests/data/test1081
+++ b/tests/data/test1081
@@ -44,16 +44,15 @@ http://%HOSTIP:%HTTPPORT/we/want/our/1081 http://%HOSTIP:%HTTPPORT/we/want/our/1
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/our/1081 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /we/want/our/10810002 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1082 b/tests/data/test1082
index 8e4078b2d..0df70afae 100644
--- a/tests/data/test1082
+++ b/tests/data/test1082
@@ -42,12 +42,10 @@ perl -e "print 'Test requires default test client host address' if ( '%CLIENTIP'
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1082 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1083 b/tests/data/test1083
index 1b1db0539..89beea0fc 100644
--- a/tests/data/test1083
+++ b/tests/data/test1083
@@ -46,12 +46,10 @@ perl -e "if ('%CLIENT6IP' ne '[::1]') {print 'Test requires default test client
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1083 HTTP/1.1
Host: %HOST6IP:%HTTP6PORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1087 b/tests/data/test1087
index 883d98642..f67429403 100644
--- a/tests/data/test1087
+++ b/tests/data/test1087
@@ -88,23 +88,23 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://first.host.it.is/we/want/that/page/10871000 HTTP/1.1
Host: first.host.it.is
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://first.host.it.is/we/want/that/page/10871000 HTTP/1.1
Host: first.host.it.is
Authorization: Basic aWFtOm15c2VsZg==
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://goto.second.host.now/10871002 HTTP/1.1
Host: goto.second.host.now
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1088 b/tests/data/test1088
index f2b6fc263..649cb88ec 100644
--- a/tests/data/test1088
+++ b/tests/data/test1088
@@ -89,24 +89,24 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://first.host.it.is/we/want/that/page/10881000 HTTP/1.1
Host: first.host.it.is
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://first.host.it.is/we/want/that/page/10881000 HTTP/1.1
Host: first.host.it.is
Authorization: Basic aWFtOm15c2VsZg==
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://goto.second.host.now/10881002 HTTP/1.1
Host: goto.second.host.now
Authorization: Basic aWFtOm15c2VsZg==
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1089 b/tests/data/test1089
index d2a18a21d..d4b879136 100644
--- a/tests/data/test1089
+++ b/tests/data/test1089
@@ -50,16 +50,15 @@ http://%HOSTIP:%HTTPPORT/1089 -w "%{num_connects}\n%{num_redirects}\n%{size_down
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1089 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /10890001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1090 b/tests/data/test1090
index 3304f911d..9ae803fb7 100644
--- a/tests/data/test1090
+++ b/tests/data/test1090
@@ -57,16 +57,15 @@ http://%HOSTIP:%HTTPPORT/1090 -w "%{num_connects}\n%{num_redirects}\n%{size_down
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1090 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /10900001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1092 b/tests/data/test1092
index 725a274ba..d3ea90244 100644
--- a/tests/data/test1092
+++ b/tests/data/test1092
@@ -43,12 +43,10 @@ FTP with type=i over HTTP proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET ftp://%HOSTIP:%HTTPPORT/we/want/that/page/1092;type=i HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1095 b/tests/data/test1095
index 6bfe54f33..3e562b037 100644
--- a/tests/data/test1095
+++ b/tests/data/test1095
@@ -65,18 +65,16 @@ http://%HOSTIP:%HTTPPORT/1095 -u testuser:testpass --digest
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1095 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /1095 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="test \"this\" realm!!", nonce="1053604145", uri="/1095", response="a1c7931ece9e8617bae2715045e4f49f"
-User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1096 b/tests/data/test1096
index 30748c1b4..a6c32c3a1 100644
--- a/tests/data/test1096
+++ b/tests/data/test1096
@@ -11,6 +11,7 @@ FAILURE
<reply>
<servercmd>
REPLY RETR 550 no such file!
+REPLY SIZE 500 command not understood
</servercmd>
</reply>
diff --git a/tests/data/test1097 b/tests/data/test1097
index 82f23846d..218d57bbe 100644
--- a/tests/data/test1097
+++ b/tests/data/test1097
@@ -59,19 +59,16 @@ http://test.a.galaxy.far.far.away.1097:%HTTPPORT/1097 --proxy http://%HOSTIP:%HT
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol nonewline="yes">
CONNECT test.a.galaxy.far.far.away.1097:%HTTPPORT HTTP/1.1
Host: test.a.galaxy.far.far.away.1097:%HTTPPORT
Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.19.5-CVS (i686-pc-linux-gnu) libcurl/7.19.5-CVS OpenSSL/0.9.8g zlib/1.2.3.3 c-ares/1.6.1-CVS libidn/1.12 libssh2/1.0.1_CVS
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
POST /1097 HTTP/1.1
-User-Agent: curl/7.19.5-CVS (i686-pc-linux-gnu) libcurl/7.19.5-CVS OpenSSL/0.9.8g zlib/1.2.3.3 c-ares/1.6.1-CVS libidn/1.12 libssh2/1.0.1_CVS
Host: test.a.galaxy.far.far.away.1097:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 11
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test1098 b/tests/data/test1098
index 0d397340c..a8d25cbe2 100644
--- a/tests/data/test1098
+++ b/tests/data/test1098
@@ -43,17 +43,16 @@ ftp://ftp-site/moo/1098 ftp://ftp-site/moo/1098 --proxy http://%HOSTIP:%HTTPPORT
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET ftp://ftp-site/moo/1098 HTTP/1.1
Host: ftp-site:21
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET ftp://ftp-site/moo/1098 HTTP/1.1
Host: ftp-site:21
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test11 b/tests/data/test11
index 9d93f80e0..3eed8a17f 100644
--- a/tests/data/test11
+++ b/tests/data/test11
@@ -59,16 +59,15 @@ http://%HOSTIP:%HTTPPORT/want/11 -L
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/11 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /want/data/110002.txt?coolsite=yes HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1100 b/tests/data/test1100
index 101b1e7ac..5bb807200 100644
--- a/tests/data/test1100
+++ b/tests/data/test1100
@@ -89,14 +89,10 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
-<protocol>
POST /1100 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
@@ -104,14 +100,14 @@ Content-Type: application/x-www-form-urlencoded
POST /1100 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAADj3hs3u3j0kgJqCrLM+74BmaoNHDfIJjHRlc3R1c2VyY3VybGhvc3Q=
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 18
Content-Type: application/x-www-form-urlencoded
stuff to send awayGET /1100 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
-User-Agent: curl/7.19.5-CVS (i686-pc-linux-gnu) libcurl/7.19.5-CVS GnuTLS/2.6.6 zlib/1.2.3.3 c-ares/1.6.1-CVS libidn/1.14 libssh2/1.1
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1101 b/tests/data/test1101
index 75c66195e..eaf16bd68 100644
--- a/tests/data/test1101
+++ b/tests/data/test1101
@@ -40,13 +40,11 @@ http://user:secret@%HOSTIP:%HTTPPORT/gimme/1101
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /gimme/1101 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Basic dXNlcjpzZWNyZXQ=
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1104 b/tests/data/test1104
index e66da58ad..2c5b9fcf7 100644
--- a/tests/data/test1104
+++ b/tests/data/test1104
@@ -68,17 +68,16 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://%HOSTIP:%HTTPPORT/want/1104 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://%HOSTIP:%HTTPPORT/want/data/11040002 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Cookie: test2=true
diff --git a/tests/data/test1105 b/tests/data/test1105
index 782044583..7ce4b67ce 100644
--- a/tests/data/test1105
+++ b/tests/data/test1105
@@ -41,12 +41,10 @@ perl -e "print 'Test requires default test server host' if ( '%HOSTIP' ne '127.0
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /we/want/1105?parm1=this*that/other/thing&parm2=foobar/1105 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 33
Content-Type: application/x-www-form-urlencoded
@@ -55,7 +53,7 @@ userid=myname&password=mypassword
</protocol>
<file name="log/cookie1105.txt" mode="text">
# Netscape HTTP Cookie File
-# https://curl.haxx.se/docs/http-cookies.html
+# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
127.0.0.1 FALSE "/silly/" FALSE 0 mismatch this
diff --git a/tests/data/test1106 b/tests/data/test1106
index 37a77e36e..e23c33c04 100644
--- a/tests/data/test1106
+++ b/tests/data/test1106
@@ -44,12 +44,10 @@ ftp://%HOSTIP:23456/1106
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET ftp://%HOSTIP:23456/1106 HTTP/1.1
Host: %HOSTIP:23456
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1109 b/tests/data/test1109
index b68b5a22f..e504ce9da 100644
--- a/tests/data/test1109
+++ b/tests/data/test1109
@@ -33,12 +33,10 @@ http://%HOSTIP:%HTTPPORT/1109#test
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1109 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1110 b/tests/data/test1110
index 94cfe9105..50bd4d20c 100644
--- a/tests/data/test1110
+++ b/tests/data/test1110
@@ -34,12 +34,10 @@ http://%HOSTIP:%HTTPPORT/1110?q=foobar#fragment
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1110?q=foobar HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1111 b/tests/data/test1111
index d9db12c7f..1ba21bffd 100644
--- a/tests/data/test1111
+++ b/tests/data/test1111
@@ -34,12 +34,10 @@ http://%HOSTIP:%HTTPPORT/1111?q=foobar#fragment#fragment2
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1111?q=foobar HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1115 b/tests/data/test1115
index f9d6e3645..0b1f034ee 100644
--- a/tests/data/test1115
+++ b/tests/data/test1115
@@ -39,12 +39,10 @@ http://%HOSTIP:%HTTPPORT/1115
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1115 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1116 b/tests/data/test1116
index b72cbd60e..ce5305d79 100644
--- a/tests/data/test1116
+++ b/tests/data/test1116
@@ -56,12 +56,10 @@ http://%HOSTIP:%HTTPPORT/1116 -D log/heads1116
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1116 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1117 b/tests/data/test1117
index 963f1efec..79c9fd4bb 100644
--- a/tests/data/test1117
+++ b/tests/data/test1117
@@ -68,18 +68,17 @@ Content-Type: text/plain
partial body
</stdout>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/1117 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Range: bytes=10-22
+User-Agent: curl/%VERSION
Accept: */*
GET /wantmore/11170001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Range: bytes=10-22
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1118 b/tests/data/test1118
index bc776aff6..702b2dfe8 100644
--- a/tests/data/test1118
+++ b/tests/data/test1118
@@ -42,12 +42,10 @@ http://%HOSTIP:%HTTPPORT?email=name@example.com/1118
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /?email=name@example.com/1118 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1119 b/tests/data/test1119
index f948976b2..7b61c706c 100644
--- a/tests/data/test1119
+++ b/tests/data/test1119
@@ -27,5 +27,4 @@ Verify that symbols-in-versions and headers are in sync
OK
</stdout>
</verify>
-
</testcase>
diff --git a/tests/data/test1121 b/tests/data/test1121
index 405066ff6..839c55364 100644
--- a/tests/data/test1121
+++ b/tests/data/test1121
@@ -34,12 +34,10 @@ HTTP multiple provided Host: headers
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1121 HTTP/1.1
Host: host1
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1122 b/tests/data/test1122
index 78d50d77b..d5b51a2cf 100644
--- a/tests/data/test1122
+++ b/tests/data/test1122
@@ -55,12 +55,10 @@ http://%HOSTIP:%HTTPPORT/1122 --tr-encoding
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1122 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Connection: TE
TE: gzip
diff --git a/tests/data/test1123 b/tests/data/test1123
index bd441a995..841a326ad 100644
--- a/tests/data/test1123
+++ b/tests/data/test1123
@@ -186,12 +186,10 @@ http://%HOSTIP:%HTTPPORT/1123 --tr-encoding
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1123 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Connection: TE
TE: gzip
diff --git a/tests/data/test1124 b/tests/data/test1124
index 58f63f930..61c5cfb6c 100644
--- a/tests/data/test1124
+++ b/tests/data/test1124
@@ -54,12 +54,10 @@ http://%HOSTIP:%HTTPPORT/1124 --tr-encoding
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1124 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Connection: TE
TE: gzip
diff --git a/tests/data/test1125 b/tests/data/test1125
index 1883734d9..51e3db783 100644
--- a/tests/data/test1125
+++ b/tests/data/test1125
@@ -55,12 +55,10 @@ http://%HOSTIP:%HTTPPORT/1125 --tr-encoding -H "Connection: close"
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1125 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Connection: close, TE
TE: gzip
diff --git a/tests/data/test1126 b/tests/data/test1126
index 52f4db411..4f99072c0 100644
--- a/tests/data/test1126
+++ b/tests/data/test1126
@@ -38,12 +38,10 @@ http://%HOSTIP:%HTTPPORT/1126 -z "dec 12 12:00:00 1999 GMT"
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1126 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
If-Modified-Since: Sun, 12 Dec 1999 12:00:00 GMT
diff --git a/tests/data/test1127 b/tests/data/test1127
index 3cc42c26a..e1453a601 100644
--- a/tests/data/test1127
+++ b/tests/data/test1127
@@ -47,12 +47,10 @@ http://%HOSTIP:%HTTPPORT/1127 -z "dec 12 12:00:00 1999 GMT"
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1127 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
If-Modified-Since: Sun, 12 Dec 1999 12:00:00 GMT
diff --git a/tests/data/test1128 b/tests/data/test1128
index a20487b43..a18f487ec 100644
--- a/tests/data/test1128
+++ b/tests/data/test1128
@@ -48,17 +48,16 @@ http://%HOSTIP:%HTTPPORT/1128 http://%HOSTIP:%HTTPPORT/11280001 -z "dec 12 12:00
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1128 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
If-Modified-Since: Sun, 12 Dec 1999 12:00:00 GMT
GET /11280001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
If-Modified-Since: Sun, 12 Dec 1999 12:00:00 GMT
diff --git a/tests/data/test1129 b/tests/data/test1129
index cc5236733..cadf80647 100644
--- a/tests/data/test1129
+++ b/tests/data/test1129
@@ -42,7 +42,7 @@ skip: 1053700
<client>
# 1053700 x 'x'
<file name="log/file1129">
-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+%repeat[1053700 x x]%
</file>
<server>
http
@@ -74,12 +74,10 @@ Content-Type: text/html
-foo-
</stdout>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
POST /1129 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 1053700
Content-Type: application/x-www-form-urlencoded
@@ -87,6 +85,7 @@ Expect: 100-continue
POST /11290001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 1053700
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test1130 b/tests/data/test1130
index eb1e59f5b..01836cd71 100644
--- a/tests/data/test1130
+++ b/tests/data/test1130
@@ -74,12 +74,10 @@ Content-Type: text/html
-foo-
</stdout>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
POST /1130 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Expect: 100-continue
Content-Length: 100
@@ -87,6 +85,7 @@ Content-Type: application/x-www-form-urlencoded
POST /11300001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Expect: 100-continue
Content-Length: 100
diff --git a/tests/data/test1131 b/tests/data/test1131
index 96843af54..64df118f7 100644
--- a/tests/data/test1131
+++ b/tests/data/test1131
@@ -74,18 +74,17 @@ Content-Type: text/html
FAILURE2
</stdout>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /1131 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 100
Expect: 100-continue
PUT /11310001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 100
Expect: 100-continue
diff --git a/tests/data/test1133 b/tests/data/test1133
index 738e80614..555bafcdd 100644
--- a/tests/data/test1133
+++ b/tests/data/test1133
@@ -40,12 +40,12 @@ foo
# Verify data after the test has been "shot"
<verify>
<strip>
-^(User-Agent:|Content-Type: multipart/form-data;|Content-Type: multipart/mixed; boundary=|-------).*
+^(Content-Type: multipart/form-data;|Content-Type: multipart/mixed; boundary=|-------).*
</strip>
<protocol>
POST /we/want/1133 HTTP/1.1
-User-Agent: curl/7.10.4 (i686-pc-linux-gnu) libcurl/7.10.4 OpenSSL/0.9.7a ipv6 zlib/1.1.3
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 1264
Content-Type: multipart/form-data; boundary=----------------------------24e78000bd32
diff --git a/tests/data/test1134 b/tests/data/test1134
index e290b5369..52aafcce1 100644
--- a/tests/data/test1134
+++ b/tests/data/test1134
@@ -45,18 +45,17 @@ http://%HOSTIP:%HTTPPORT/1134 -u user1:password1 --next http://%HOSTIP:%HTTPPORT
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1134 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Basic dXNlcjE6cGFzc3dvcmQx
+User-Agent: curl/%VERSION
Accept: */*
GET /11340001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Basic MnVzZXI6cGFzc3dvcmQy
+User-Agent: curl/%VERSION
Accept: */*
[DISCONNECT]
diff --git a/tests/data/test1136 b/tests/data/test1136
index 75b6ee838..7415072c8 100644
--- a/tests/data/test1136
+++ b/tests/data/test1136
@@ -54,7 +54,7 @@ http://www.example.ck/1136 http://www.ck/1136 http://z-1.compute-1.amazonaws.com
<verify>
<file name="log/jar1136.txt" mode="text">
# Netscape HTTP Cookie File
-# https://curl.haxx.se/docs/http-cookies.html
+# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
.z-1.compute-1.amazonaws.com TRUE / FALSE 0 test5 forbidden5
diff --git a/tests/data/test1138 b/tests/data/test1138
index 0c91d204d..a69d40fd2 100644
--- a/tests/data/test1138
+++ b/tests/data/test1138
@@ -56,17 +56,15 @@ http://%HOSTIP:%HTTPPORT/we/are/all/twits/1138 -L
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/are/all/twits/1138 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /we/are/all/moo.html/?name=%d8%a2%d8%ba%d8%a7%d8%b2-%d8%b3%d9%85-%d8%b2%d8%af%d8%a7%db%8c%db%8c-%d8%a7%d8%b2-%d8%a8%d8%a7%d8%b2%d8%a7%d8%b1-%d9%be%d9%88%d9%84&testcase=/11380002 HTTP/1.1
-User-Agent: curl/7.10 (i686-pc-linux-gnu) libcurl/7.10 OpenSSL/0.9.6c ipv6 zlib/1.1.3
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1141 b/tests/data/test1141
index b0cff8e37..063d3b284 100644
--- a/tests/data/test1141
+++ b/tests/data/test1141
@@ -54,17 +54,16 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://%HOSTIP:%HTTPPORT/want/1141 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://foo.example.com/want/11410001 HTTP/1.1
Host: foo.example.com
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1142 b/tests/data/test1142
index 5f1e2b35a..3577ac468 100644
--- a/tests/data/test1142
+++ b/tests/data/test1142
@@ -49,12 +49,10 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://%HOSTIP:%HTTPPORT/want/1142 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1143 b/tests/data/test1143
index 7776cfa87..8239c444f 100644
--- a/tests/data/test1143
+++ b/tests/data/test1143
@@ -37,12 +37,10 @@ MSYS2_ARG_CONV_EXCL=http:/
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/1143 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1144 b/tests/data/test1144
index 84c22dba2..588355569 100644
--- a/tests/data/test1144
+++ b/tests/data/test1144
@@ -54,12 +54,10 @@ HTTP HEAD, receive no headers only body
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
HEAD /1144 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1148 b/tests/data/test1148
index c4232f083..a4839e27c 100644
--- a/tests/data/test1148
+++ b/tests/data/test1148
@@ -45,12 +45,10 @@ LC_NUMERIC=en_US.UTF-8
#
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1148 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1150 b/tests/data/test1150
index e86c7e154..f951f570e 100644
--- a/tests/data/test1150
+++ b/tests/data/test1150
@@ -39,17 +39,16 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
GET http://test.remote.example.com.1150:150/path HTTP/1.1
Host: test.remote.example.com.1150:150
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://test.remote.example.com.1150:1234/path/ HTTP/1.1
Host: test.remote.example.com.1150:1234
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1151 b/tests/data/test1151
index d793944c3..c0e5bc1de 100644
--- a/tests/data/test1151
+++ b/tests/data/test1151
@@ -44,18 +44,16 @@ http://%HOSTIP:%HTTPPORT/1151 -c log/cookies1151.txt
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1151 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
<file name="log/cookies1151.txt" mode="text">
# Netscape HTTP Cookie File
-# https://curl.haxx.se/docs/http-cookies.html
+# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
127.0.0.1 FALSE / FALSE 0 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF E
diff --git a/tests/data/test1154 b/tests/data/test1154
index 3582eb99a..8213528c9 100644
--- a/tests/data/test1154
+++ b/tests/data/test1154
@@ -15,7 +15,7 @@ Date: Thu, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Content-Length: 6
Connection: close
-Long: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+Long: %repeat[102400 x A]%
-foo-
</data>
@@ -40,12 +40,10 @@ http://%HOSTIP:%HTTPPORT/1154
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1154 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1155 b/tests/data/test1155
index 3db824d58..82007407c 100644
--- a/tests/data/test1155
+++ b/tests/data/test1155
@@ -34,18 +34,16 @@ http://%HOSTIP:%HTTPPORT/1155 -c log/cookies1155.txt
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1155 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
<file name="log/cookies1155.txt" mode="text">
# Netscape HTTP Cookie File
-# https://curl.haxx.se/docs/http-cookies.html
+# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
127.0.0.1 FALSE / FALSE 0 domain value
diff --git a/tests/data/test1157 b/tests/data/test1157
index b0bbf244f..baf12edb4 100644
--- a/tests/data/test1157
+++ b/tests/data/test1157
@@ -45,12 +45,10 @@ http://%HOSTIP:%HTTPPORT/1157 -H @log/heads1157.txt
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1157 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1158 b/tests/data/test1158
index 62adc579d..f2b40e01b 100644
--- a/tests/data/test1158
+++ b/tests/data/test1158
@@ -43,12 +43,12 @@ foo
# Verify data after the test has been "shot"
<verify>
<strip>
-^(User-Agent:|Content-Type: multipart/form-data;|Content-Type: multipart/mixed; boundary=|-------).*
+^(Content-Type: multipart/form-data;|Content-Type: multipart/mixed; boundary=|-------).*
</strip>
<protocol>
POST /we/want/1158 HTTP/1.1
-User-Agent: curl/7.10.4 (i686-pc-linux-gnu) libcurl/7.10.4 OpenSSL/0.9.7a ipv6 zlib/1.1.3
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 954
Content-Type: multipart/form-data; boundary=----------------------------24e78000bd32
diff --git a/tests/data/test1159 b/tests/data/test1159
index a51601659..ea07f238f 100644
--- a/tests/data/test1159
+++ b/tests/data/test1159
@@ -36,12 +36,10 @@ http://%HOSTIP:%HTTPPORT/we/want/our/1159 -w '%{redirect_url}\n'
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/our/1159 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1160 b/tests/data/test1160
index 63dd0a7a0..1ea4cc084 100644
--- a/tests/data/test1160
+++ b/tests/data/test1160
@@ -35,18 +35,16 @@ http://%HOSTIP:%HTTPPORT/1160 -c log/cookies1160.txt
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1160 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
<file name="log/cookies1160.txt" mode="text">
# Netscape HTTP Cookie File
-# https://curl.haxx.se/docs/http-cookies.html
+# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
</file>
diff --git a/tests/data/test1161 b/tests/data/test1161
index ee6f1d04a..ae7f141f8 100644
--- a/tests/data/test1161
+++ b/tests/data/test1161
@@ -34,18 +34,16 @@ http://%HOSTIP:%HTTPPORT/1161 -c log/cookies1161.txt
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1161 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
<file name="log/cookies1161.txt" mode="text">
# Netscape HTTP Cookie File
-# https://curl.haxx.se/docs/http-cookies.html
+# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
127.0.0.1 FALSE / FALSE 0 ckyPersistent permanent
diff --git a/tests/data/test1164 b/tests/data/test1164
index a5ce6d11a..f62b0f66e 100644
--- a/tests/data/test1164
+++ b/tests/data/test1164
@@ -36,12 +36,10 @@ http://%HOSTIP:%HTTPPORT/1164 -w '%{size_download}\n' --http0.9
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1164 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1166 b/tests/data/test1166
index 3cae80ecd..292d09fc3 100644
--- a/tests/data/test1166
+++ b/tests/data/test1166
@@ -36,16 +36,15 @@ http://%HOSTIP:%HTTPPORT/want/1166 http://%HOSTIP:%HTTPPORT/want/1166
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/1166 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /want/1166 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1168 b/tests/data/test1168
index 283e91e01..b2f08fb61 100644
--- a/tests/data/test1168
+++ b/tests/data/test1168
@@ -59,18 +59,17 @@ http://%HOSTIP:%HTTPPORT/want/1168 -L -u "catmai#d:#DZaRJYrixKE*gFY"
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/1168 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Basic Y2F0bWFpI2Q6I0RaYVJKWXJpeEtFKmdGWQ==
+User-Agent: curl/%VERSION
Accept: */*
GET /data/11680002.txt HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Basic Y2F0bWFpI2Q6I0RaYVJKWXJpeEtFKmdGWQ==
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1170 b/tests/data/test1170
index a4d9eb84b..39ff3c8c9 100644
--- a/tests/data/test1170
+++ b/tests/data/test1170
@@ -55,12 +55,10 @@ http://%HOSTIP:%HTTPPORT/1170 --tr-encoding -H "Connection:"
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1170 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Connection: TE
TE: gzip
diff --git a/tests/data/test1171 b/tests/data/test1171
index 0f7ee90d3..bc98d312e 100644
--- a/tests/data/test1171
+++ b/tests/data/test1171
@@ -55,12 +55,10 @@ http://%HOSTIP:%HTTPPORT/1171 --tr-encoding -H "Connection;"
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1171 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Connection: TE
TE: gzip
diff --git a/tests/data/test1172 b/tests/data/test1172
index 6e61720bd..a099057f2 100644
--- a/tests/data/test1172
+++ b/tests/data/test1172
@@ -33,12 +33,10 @@ http://%HOSTIP:%HTTPPORT/1172 --no-http0.9
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1172 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1174 b/tests/data/test1174
index b316fde8c..7768696ff 100644
--- a/tests/data/test1174
+++ b/tests/data/test1174
@@ -33,12 +33,10 @@ http://%HOSTIP:%HTTPPORT/1174
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1174 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1176 b/tests/data/test1176
index 491bee16f..ce992e341 100644
--- a/tests/data/test1176
+++ b/tests/data/test1176
@@ -41,12 +41,10 @@ http://%HOSTIP:%HTTPPORT/1176 -o 'log/base-#0'
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1176 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1178 b/tests/data/test1178
index 6d1264c35..91ef78c8f 100644
--- a/tests/data/test1178
+++ b/tests/data/test1178
@@ -40,13 +40,11 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://%HOSTIP:%HTTPPORT/we/want/that/page/1178 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Proxy-Authorization: Basic QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQTpCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkI=
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test118 b/tests/data/test118
index 6cd086ca2..94985e319 100644
--- a/tests/data/test118
+++ b/tests/data/test118
@@ -12,6 +12,7 @@ FAILURE
<servercmd>
REPLY RETR 314 bluah you f00l!
REPLY EPSV 314 bluah you f00l!
+REPLY SIZE 500 command not understood
</servercmd>
</reply>
diff --git a/tests/data/test119 b/tests/data/test119
index 00a24287b..95d1021ca 100644
--- a/tests/data/test119
+++ b/tests/data/test119
@@ -11,6 +11,7 @@ FAILURE
<reply>
<servercmd>
REPLY RETR 314 bluah you f00l!
+REPLY SIZE 500 command not understood
</servercmd>
</reply>
diff --git a/tests/data/test1197 b/tests/data/test1197
index 96d368f8b..1abd9aeb5 100644
--- a/tests/data/test1197
+++ b/tests/data/test1197
@@ -50,18 +50,17 @@ http://%HOSTIP:%HTTPPORT/1197 -w "%{method}\n" -L -d "twinkle twinkle little sta
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
POST /1197 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 27
Content-Type: application/x-www-form-urlencoded
twinkle twinkle little starGET /11970001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test12 b/tests/data/test12
index 06dbdf56f..8f93abbaa 100644
--- a/tests/data/test12
+++ b/tests/data/test12
@@ -42,13 +42,11 @@ http://%HOSTIP:%HTTPPORT/want/12 -r 100-200
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/12 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Range: bytes=100-200
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1204 b/tests/data/test1204
index d2f06b68e..50738011c 100644
--- a/tests/data/test1204
+++ b/tests/data/test1204
@@ -61,17 +61,16 @@ http://%HOSTIP:%HTTPPORT/1204 -u testuser:testpass --anyauth
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1204 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /1204 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Basic dGVzdHVzZXI6dGVzdHBhc3M=
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1205 b/tests/data/test1205
index 7e4a882c7..8509d3fd5 100644
--- a/tests/data/test1205
+++ b/tests/data/test1205
@@ -37,12 +37,10 @@ http://%HOSTIP:%HTTPPORT/1205
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1205 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1210 b/tests/data/test1210
index df931988c..71053f218 100644
--- a/tests/data/test1210
+++ b/tests/data/test1210
@@ -46,12 +46,10 @@ http://%HOSTIP:%HTTPPORT/1210 -J -O
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1210 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1212 b/tests/data/test1212
index a50601f78..7c2af2e54 100644
--- a/tests/data/test1212
+++ b/tests/data/test1212
@@ -37,13 +37,11 @@ http://user:secret@%HOSTIP:%HTTPPORT/ulion/1212 --socks5 non-existing-host.haxx.
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /ulion/1212 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Basic dXNlcjpzZWNyZXQ=
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1213 b/tests/data/test1213
index 46a6938cb..54a8f2d99 100644
--- a/tests/data/test1213
+++ b/tests/data/test1213
@@ -42,12 +42,10 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://we.want.that.site.com.1213/ HTTP/1.1
Host: we.want.that.site.com.1213
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1214 b/tests/data/test1214
index 73c799a4a..985fd383b 100644
--- a/tests/data/test1214
+++ b/tests/data/test1214
@@ -42,12 +42,10 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://we.want.that.site.com.1214/?moo=foo HTTP/1.1
Host: we.want.that.site.com.1214
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1215 b/tests/data/test1215
index ed50da0b8..7aa1c4237 100644
--- a/tests/data/test1215
+++ b/tests/data/test1215
@@ -85,21 +85,18 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://%HOSTIP:%HTTPPORT/1215 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.30.0-DEV
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://%HOSTIP:%HTTPPORT/1215 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAADj3hs3u3j0kgJqCrLM+74BmaoNHDfIJjHRlc3R1c2VyY3VybGhvc3Q=
-User-Agent: curl/7.30.0-DEV
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1216 b/tests/data/test1216
index c4f977b60..622713323 100644
--- a/tests/data/test1216
+++ b/tests/data/test1216
@@ -46,18 +46,17 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://example.fake/c/1216 HTTP/1.1
Host: example.fake
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Cookie: moo3=indeed; moo2=indeed
GET http://bexample.fake/c/1216 HTTP/1.1
Host: bexample.fake
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1218 b/tests/data/test1218
index 37c8f4ef0..b9914d25f 100644
--- a/tests/data/test1218
+++ b/tests/data/test1218
@@ -39,23 +39,23 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://example.fake/c/1218 HTTP/1.1
Host: example.fake
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://example.fake/c/1218 HTTP/1.1
Host: example.fake
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Cookie: bug=fixed
GET http://bexample.fake/c/1218 HTTP/1.1
Host: bexample.fake
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1221 b/tests/data/test1221
deleted file mode 100644
index 15700f449..000000000
--- a/tests/data/test1221
+++ /dev/null
@@ -1,53 +0,0 @@
-<testcase>
-<info>
-<keywords>
-build system
-source analysis
-</keywords>
-</info>
-
-#
-# Client-side
-<client>
-<server>
-none
-</server>
-
-<name>
-10 chars object name generation testing
-</name>
-<command option="no-output,no-include" type="shell">
-%SRCDIR/objnames-test10.sh %SRCDIR
-</command>
-</client>
-
-#
-# Verify data after the test has been "shot"
-<verify>
-<file1 name="log/stderr1221" mode="text">
-</file1>
-<file2 name="log/stdout1221">
-Testing curl_10char_object_name...
-
-result: 16AFKPQRST expected: 16AFKPQRST input: 123__678__ABC__FGH__KLM__PQRSTUV
-result: 16AFKPQ expected: 16AFKPQ input: 123__678__ABC__FGH__KLM__PQ.S.UV
-result: 16ABC expected: 16ABC input: 123__678__ABC..FGH..KLM..PQRSTUV
-result: 16 expected: 16 input: 123__678_.ABC._FGH__KLM__PQRSTUV
-result: 123 expected: 123 input: 123.567.90ABCDEFGHIJKLMNOPQRSTUV
-result: 1234567 expected: 1234567 input: 1234567.90A.CDEFGHIJKLMNOPQRSTUV
-result: 1234567890 expected: 1234567890 input: 1234567890.BCD.FGHIJKLMNOPQRSTUV
-result: 1470AB expected: 1470AB input: 12=45-78+0AB.DE.GHIJKLMNOPQRSTUV
-result: 1234567890 expected: 1234567890 input: 1234567890ABCDEFGHIJKLMNOPQRSTUV
-result: 159CGHIJKL expected: 159CGHIJKL input: 123_567_90A_CDE_GHIJKLMNOPQRSTUV
-result: 159CDEFGHI expected: 159CDEFGHI input: 123_567_90A_CDEFGHIJKLMNOPQRSTUV
-result: 1590ABCDEF expected: 1590ABCDEF input: 123_567_90ABCDEFGHIJKLMNOPQRSTUV
-result: 1567890ABC expected: 1567890ABC input: 123_567890ABCDEFGHIJKLMNOPQRSTUV
-result: 1234567890 expected: 1234567890 input: 1234567890ABCDEFGHIJKLMNOPQRSTUV
-
-
-
-10-characters-or-less generated object names are unique.
-</file2>
-</verify>
-
-</testcase>
diff --git a/tests/data/test1222 b/tests/data/test1222
deleted file mode 100644
index 5eab55ba1..000000000
--- a/tests/data/test1222
+++ /dev/null
@@ -1,53 +0,0 @@
-<testcase>
-<info>
-<keywords>
-build system
-source analysis
-</keywords>
-</info>
-
-#
-# Client-side
-<client>
-<server>
-none
-</server>
-
-<name>
-8 chars object name generation testing
-</name>
-<command option="no-output,no-include" type="shell">
-%SRCDIR/objnames-test08.sh %SRCDIR
-</command>
-</client>
-
-#
-# Verify data after the test has been "shot"
-<verify>
-<file1 name="log/stderr1222">
-</file1>
-<file2 name="log/stdout1222">
-Testing curl_8char_object_name...
-
-result: 16AFKPQR expected: 16AFKPQR input: 123__678__ABC__FGH__KLM__PQRSTUV
-result: 16AFKPQ expected: 16AFKPQ input: 123__678__ABC__FGH__KLM__PQ.S.UV
-result: 16ABC expected: 16ABC input: 123__678__ABC..FGH..KLM..PQRSTUV
-result: 16 expected: 16 input: 123__678_.ABC._FGH__KLM__PQRSTUV
-result: 123 expected: 123 input: 123.567.90ABCDEFGHIJKLMNOPQRSTUV
-result: 1234567 expected: 1234567 input: 1234567.90A.CDEFGHIJKLMNOPQRSTUV
-result: 12345678 expected: 12345678 input: 1234567890.BCD.FGHIJKLMNOPQRSTUV
-result: 1470AB expected: 1470AB input: 12=45-78+0AB.DE.GHIJKLMNOPQRSTUV
-result: 12345678 expected: 12345678 input: 1234567890ABCDEFGHIJKLMNOPQRSTUV
-result: 159CGHIJ expected: 159CGHIJ input: 123_567_90A_CDE_GHIJKLMNOPQRSTUV
-result: 159CDEFG expected: 159CDEFG input: 123_567_90A_CDEFGHIJKLMNOPQRSTUV
-result: 1590ABCD expected: 1590ABCD input: 123_567_90ABCDEFGHIJKLMNOPQRSTUV
-result: 1567890A expected: 1567890A input: 123_567890ABCDEFGHIJKLMNOPQRSTUV
-result: 12345678 expected: 12345678 input: 1234567890ABCDEFGHIJKLMNOPQRSTUV
-
-
-
-8-characters-or-less generated object names are unique.
-</file2>
-</verify>
-
-</testcase>
diff --git a/tests/data/test1223 b/tests/data/test1223
index 2885bc59a..f448f5c14 100644
--- a/tests/data/test1223
+++ b/tests/data/test1223
@@ -37,12 +37,10 @@ http://%HOSTIP:%HTTPPORT/1223 -w 'IP %{remote_ip} and PORT %{remote_port}\n'
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1223 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1228 b/tests/data/test1228
index 50af6bc2c..529c7e55d 100644
--- a/tests/data/test1228
+++ b/tests/data/test1228
@@ -38,17 +38,16 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://example.fake/hoge/1228 HTTP/1.1
Host: example.fake
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://example.fake/hogege/ HTTP/1.1
Host: example.fake
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Cookie: path1=root
diff --git a/tests/data/test1229 b/tests/data/test1229
index 225ba3cc4..0cb45358a 100644
--- a/tests/data/test1229
+++ b/tests/data/test1229
@@ -65,17 +65,16 @@ http://%5cuser%22:password@%HOSTIP:%HTTPPORT/1229 --digest
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1229 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /1229 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="\\user\"", realm="testrealm", nonce="1053604145", uri="/1229", response="f2694d426040712584c156d3de72b8d6"
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1230 b/tests/data/test1230
index 860ce21a4..a439b17ed 100644
--- a/tests/data/test1230
+++ b/tests/data/test1230
@@ -62,16 +62,15 @@ http://[1234:1234:1234::4ce]:%HTTPPORT/wanted/page/1230 -p -x %HOSTIP:%HTTPPORT
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
CONNECT [1234:1234:1234::4ce]:%HTTPPORT HTTP/1.1
Host: [1234:1234:1234::4ce]:%HTTPPORT
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
GET /wanted/page/1230 HTTP/1.1
Host: [1234:1234:1234::4ce]:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1231 b/tests/data/test1231
index 61998d1c3..7b085c523 100644
--- a/tests/data/test1231
+++ b/tests/data/test1231
@@ -44,16 +44,15 @@ http://%HOSTIP:%HTTPPORT/../../hej/but/who/../1231?stupid=me/../1231#soo/../1231
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /hej/but/1231?stupid=me/../1231 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /hej/but/12310001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1232 b/tests/data/test1232
index 7425d44d8..7a74cb12d 100644
--- a/tests/data/test1232
+++ b/tests/data/test1232
@@ -49,17 +49,16 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://test.remote.haxx.se.1232:8990/hej/but/1232?stupid=me/../1232 HTTP/1.1
Host: test.remote.haxx.se.1232:8990
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://test.remote.haxx.se.1232:8990/hej/but/12320001 HTTP/1.1
Host: test.remote.haxx.se.1232:8990
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1235 b/tests/data/test1235
index 9e51219ff..3fffb4209 100644
--- a/tests/data/test1235
+++ b/tests/data/test1235
@@ -40,28 +40,25 @@ multiple requests using {}{} in the URL
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /12350001 HTTP/1.1
-User-Agent: curl/7.8.1-pre3 (sparc-sun-solaris2.7) libcurl 7.8.1-pre3 (OpenSSL 0.9.6a) (krb4 enabled)
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /12350002 HTTP/1.1
-User-Agent: curl/7.8.1-pre3 (sparc-sun-solaris2.7) libcurl 7.8.1-pre3 (OpenSSL 0.9.6a) (krb4 enabled)
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /12350001 HTTP/1.1
-User-Agent: curl/7.8.1-pre3 (sparc-sun-solaris2.7) libcurl 7.8.1-pre3 (OpenSSL 0.9.6a) (krb4 enabled)
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /12350002 HTTP/1.1
-User-Agent: curl/7.8.1-pre3 (sparc-sun-solaris2.7) libcurl 7.8.1-pre3 (OpenSSL 0.9.6a) (krb4 enabled)
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1237 b/tests/data/test1237
index 21da17dcf..a016e5fb6 100644
--- a/tests/data/test1237
+++ b/tests/data/test1237
@@ -33,13 +33,11 @@ URL with 1000+ letter user name + password
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1237 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Basic QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQTpCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkI=
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1239 b/tests/data/test1239
index b3503d9c4..375d92b68 100644
--- a/tests/data/test1239
+++ b/tests/data/test1239
@@ -41,12 +41,10 @@ http://%HOSTIP:%HTTPPORT/1239 -z "-dec 12 12:00:00 1999 GMT" -w '%{response_code
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1239 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
If-Unmodified-Since: Sun, 12 Dec 1999 12:00:00 GMT
diff --git a/tests/data/test1240 b/tests/data/test1240
index 643595058..44ce1f69b 100644
--- a/tests/data/test1240
+++ b/tests/data/test1240
@@ -31,16 +31,15 @@ glob [0-1] with stuff after range (7.33.0 regression)
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /00/1240 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /01/1240 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1241 b/tests/data/test1241
index bc6c61801..0089828f8 100644
--- a/tests/data/test1241
+++ b/tests/data/test1241
@@ -48,17 +48,16 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://test.remote.haxx.se.1241:8990/../../hej/but/who/../1241?stupid=me/../1241 HTTP/1.1
Host: test.remote.haxx.se.1241:8990
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://test.remote.haxx.se.1241:8990/../../hej/but/who/../12410001 HTTP/1.1
Host: test.remote.haxx.se.1241:8990
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1244 b/tests/data/test1244
index 0912c0947..c2ac4a4d1 100644
--- a/tests/data/test1244
+++ b/tests/data/test1244
@@ -50,12 +50,10 @@ http://%HOSTIP:%HTTPPORT/1244 -x %HOSTIP:%HTTPPORT --next http://%HOSTIP:%HTTPPO
<errorcode>
56
</errorcode>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://%HOSTIP:%HTTPPORT/1244 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1245 b/tests/data/test1245
index 8924bff97..d60ff2bc1 100644
--- a/tests/data/test1245
+++ b/tests/data/test1245
@@ -42,12 +42,10 @@ ftp
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1245 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1246 b/tests/data/test1246
index a35bc89c3..bc3d2b000 100644
--- a/tests/data/test1246
+++ b/tests/data/test1246
@@ -48,17 +48,16 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://test.remote.haxx.se.1246:%HTTPPORT/ HTTP/1.1
Host: test.remote.haxx.se.1246:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://no-scheme-url.com.1246:%HTTPPORT/ HTTP/1.1
Host: no-scheme-url.com.1246:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1248 b/tests/data/test1248
index 02dacfc8b..7410483b8 100644
--- a/tests/data/test1248
+++ b/tests/data/test1248
@@ -35,13 +35,11 @@ http://user:secret@%HOSTIP:%HTTPPORT/1248 --proxy http://dummy:%NOLISTENPORT/ --
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1248 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Basic dXNlcjpzZWNyZXQ=
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1249 b/tests/data/test1249
index 1bc3cfe59..13a14630a 100644
--- a/tests/data/test1249
+++ b/tests/data/test1249
@@ -38,13 +38,11 @@ http://user:secret@%HOSTIP:%HTTPPORT/1249 --proxy http://dummy:%NOLISTENPORT/ --
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1249 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Basic dXNlcjpzZWNyZXQ=
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1250 b/tests/data/test1250
index bf67b7fe7..acd670e50 100644
--- a/tests/data/test1250
+++ b/tests/data/test1250
@@ -39,13 +39,11 @@ http://user:secret@%HOSTIP:%HTTPPORT/1250 --noproxy %HOSTIP --max-time 5
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1250 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Basic dXNlcjpzZWNyZXQ=
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1251 b/tests/data/test1251
index f37a685e8..f5cf51303 100644
--- a/tests/data/test1251
+++ b/tests/data/test1251
@@ -40,13 +40,11 @@ http://user:secret@%HOSTIP:%HTTPPORT/1251 --max-time 5
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1251 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Basic dXNlcjpzZWNyZXQ=
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1252 b/tests/data/test1252
index cbaef48b7..e68fcb918 100644
--- a/tests/data/test1252
+++ b/tests/data/test1252
@@ -39,12 +39,10 @@ http://%HOSTIP:%HTTPPORT/1252 --proxy http://%HOSTIP:%HTTPPORT --noproxy %HOSTIP
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1252 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1253 b/tests/data/test1253
index 8f240b0af..7ad1f86f2 100644
--- a/tests/data/test1253
+++ b/tests/data/test1253
@@ -42,12 +42,10 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://somewhere.example.com/1253 HTTP/1.1
Host: somewhere.example.com
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1254 b/tests/data/test1254
index c05975488..b2f27f94e 100644
--- a/tests/data/test1254
+++ b/tests/data/test1254
@@ -42,12 +42,10 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://somewhere.example.com/1254 HTTP/1.1
Host: somewhere.example.com
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1255 b/tests/data/test1255
index d82310f67..9148a56ce 100644
--- a/tests/data/test1255
+++ b/tests/data/test1255
@@ -40,12 +40,10 @@ http://%HOSTIP:%HTTPPORT/1255 --noproxy %HOSTIP
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1255 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1256 b/tests/data/test1256
index e86afbb53..1ba0a0983 100644
--- a/tests/data/test1256
+++ b/tests/data/test1256
@@ -43,12 +43,10 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://somewhere.example.com/1256 HTTP/1.1
Host: somewhere.example.com
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1257 b/tests/data/test1257
index 16a7c1af6..b05c524ba 100644
--- a/tests/data/test1257
+++ b/tests/data/test1257
@@ -43,12 +43,10 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://somewhere.example.com/1257 HTTP/1.1
Host: somewhere.example.com
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1258 b/tests/data/test1258
index 6fa88e16e..297460c85 100644
--- a/tests/data/test1258
+++ b/tests/data/test1258
@@ -36,16 +36,15 @@ http://%HOSTIP:%HTTPPORT/we/want/1258 http://%HOSTIP:%HTTPPORT/we/want?hoge=fuga
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/1258 HTTP/1.1
Host: localhost
+User-Agent: curl/%VERSION
Accept: */*
GET /we/want?hoge=fuga HTTP/1.1
Host: localhost
+User-Agent: curl/%VERSION
Accept: */*
Cookie: I-am=here
diff --git a/tests/data/test1259 b/tests/data/test1259
index bad4ee25e..0bfa71cdc 100644
--- a/tests/data/test1259
+++ b/tests/data/test1259
@@ -33,13 +33,11 @@ HTTP URL with semicolon in password
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/1259 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Basic dXNlcjpwYXNzO3dvcmQ=
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1261 b/tests/data/test1261
index 7f887994e..ef3cded57 100644
--- a/tests/data/test1261
+++ b/tests/data/test1261
@@ -36,12 +36,10 @@ http://%HOSTIP:%HTTPPORT/we/want/our/1261 -w '%{redirect_url}\n' --location --ma
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/our/1261 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1265 b/tests/data/test1265
index 5d3ef6dc8..12d524319 100644
--- a/tests/data/test1265
+++ b/tests/data/test1265
@@ -40,12 +40,10 @@ http://%HOST6IP:%HTTP6PORT/1265
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1265 HTTP/1.1
Host: %HOST6IP:%HTTP6PORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1266 b/tests/data/test1266
index cab11efa0..1de936e03 100644
--- a/tests/data/test1266
+++ b/tests/data/test1266
@@ -33,12 +33,10 @@ http://%HOSTIP:%HTTPPORT/1266 --http0.9
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1266 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1267 b/tests/data/test1267
index 82d37445d..06500e87b 100644
--- a/tests/data/test1267
+++ b/tests/data/test1267
@@ -33,12 +33,10 @@ http://%HOSTIP:%HTTPPORT/1267 --http0.9
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1267 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1270 b/tests/data/test1270
index 25799818a..680e1e47c 100644
--- a/tests/data/test1270
+++ b/tests/data/test1270
@@ -41,12 +41,10 @@ http://%HOSTIP:%HTTPPORT/we/want/our/1270 -w '%{redirect_url}\n' -s
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/our/1270 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1271 b/tests/data/test1271
index 687a6a979..ce89c38f2 100644
--- a/tests/data/test1271
+++ b/tests/data/test1271
@@ -35,12 +35,10 @@ http://%HOSTIP:%HTTPPORT/we/want/our/1271 -w @log/blank1271
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/our/1271 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1280 b/tests/data/test1280
index 15c1e2fd1..0b7bc0045 100644
--- a/tests/data/test1280
+++ b/tests/data/test1280
@@ -33,24 +33,25 @@ http://%HOSTIP:%HTTPPORT/[a-d]/1280
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /a/1280 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /b/1280 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /c/1280 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /d/1280 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1283 b/tests/data/test1283
index ac275e92e..d4c0ad964 100644
--- a/tests/data/test1283
+++ b/tests/data/test1283
@@ -36,12 +36,10 @@ http://%HOSTIP:%HTTPPORT/[a-a][1-1][b-b:1][2-2:1]/1283 -o "log/outfile1283_#1#2#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /a1b2/1283 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1284 b/tests/data/test1284
index 8437a4082..4509a9b91 100644
--- a/tests/data/test1284
+++ b/tests/data/test1284
@@ -66,12 +66,10 @@ HTTP POST --digest with user-specified Content-Length header
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /1284 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
@@ -79,6 +77,7 @@ Content-Type: application/x-www-form-urlencoded
POST /1284 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="auser", realm="testrealm", nonce="1053604144", uri="/1284", response="5763079608de439072861a59ac733515"
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 11
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test1285 b/tests/data/test1285
index 16c66238a..62828ba4f 100644
--- a/tests/data/test1285
+++ b/tests/data/test1285
@@ -72,18 +72,17 @@ four is the number of lines
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /1285 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 0
PUT /1285 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="auser", realm="testrealm", nonce="1053604144", uri="/1285", response="dc185587d5e8391b347eef194c2a3cd6"
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 85
Expect: 100-continue
diff --git a/tests/data/test1286 b/tests/data/test1286
index 41782cb0f..c64a79b47 100644
--- a/tests/data/test1286
+++ b/tests/data/test1286
@@ -77,9 +77,7 @@ HTTP GET --digest increasing nonce-count
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
+
# Reorder the fields in 'Authorization: Digest' header.
# Since regular and SSPI digest auth header fields may not have the same order
# or whitespace we homogenize so that both may be tested. Also:
@@ -93,16 +91,19 @@ if(s/^(Authorization: Digest )([^\r\n]+)(\r?\n)$//) { $_ = $1 . join(', ', map {
<protocol>
GET /1286 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /1286 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest cnonce=REMOVED, nc=00000001, nonce="1053604144", qop=auth, realm="testrealm", response=REMOVED, uri="/1286", username="auser"
+User-Agent: curl/%VERSION
Accept: */*
GET /12860001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest cnonce=REMOVED, nc=00000002, nonce="1053604144", qop=auth, realm="testrealm", response=REMOVED, uri="/12860001", username="auser"
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1287 b/tests/data/test1287
index 976fd6ecf..d53a72b8e 100644
--- a/tests/data/test1287
+++ b/tests/data/test1287
@@ -68,18 +68,17 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<proxy>
CONNECT test.1287:%HTTPPORT HTTP/1.1
Host: test.1287:%HTTPPORT
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
</proxy>
<protocol>
GET /we/want/that/page/1287 HTTP/1.1
Host: test.1287:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1288 b/tests/data/test1288
index d8a1e524c..a841709be 100644
--- a/tests/data/test1288
+++ b/tests/data/test1288
@@ -52,18 +52,17 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<proxy>
CONNECT %HOSTIP.1288:%HTTPPORT HTTP/1.1
Host: %HOSTIP.1288:%HTTPPORT
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
</proxy>
<protocol>
GET /we/want/that/page/1288 HTTP/1.1
Host: %HOSTIP.1288:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1290 b/tests/data/test1290
index e556303bf..871dcd763 100644
--- a/tests/data/test1290
+++ b/tests/data/test1290
@@ -35,12 +35,10 @@ Verify URL globbing ignores []
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/[]/page/1290 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1292 b/tests/data/test1292
index 880a4b465..dee0def3e 100644
--- a/tests/data/test1292
+++ b/tests/data/test1292
@@ -37,12 +37,10 @@ Replaced internal headers with a blank one
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1292 HTTP/1.1
Host:
+User-Agent: curl/%VERSION
Accept:
</protocol>
diff --git a/tests/data/test1293 b/tests/data/test1293
index e2143d103..df72b755a 100644
--- a/tests/data/test1293
+++ b/tests/data/test1293
@@ -43,9 +43,6 @@ http://0 http://%HOSTIP:%HTTPPORT/1293 -F=
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<strippart>
s/^--------------------------[a-z0-9]*/------------------------------/
s/boundary=------------------------[a-z0-9]*/boundary=----------------------------/
@@ -53,6 +50,7 @@ s/boundary=------------------------[a-z0-9]*/boundary=--------------------------
<protocol>
POST /1293 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 126
Content-Type: multipart/form-data; boundary=----------------------------
diff --git a/tests/data/test1294 b/tests/data/test1294
index 1c2c0ef95..4fa1cb1d9 100644
--- a/tests/data/test1294
+++ b/tests/data/test1294
@@ -51,12 +51,10 @@ http://%HOSTIP:%HTTPPORT/0123456790123456790123456790123456790123456790123456790
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679/1294 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Among other public buildings in a certain town, which for many reasons it will be prudent to refrain from mentioning, and to which I will assign no fictitious name, there is one anciently common to most towns, great or small to wit, a workhouse; and in this workhouse was born; on a day and date which I need not trouble myself to repeat, inasmuch as it can be of no possible consequence to the reader, in this stage of the business at all events; the item of mortality whose name is prefixed to the head of this chapter: 511
diff --git a/tests/data/test1295 b/tests/data/test1295
index b929e3c6d..50e5fa2e2 100644
--- a/tests/data/test1295
+++ b/tests/data/test1295
@@ -51,12 +51,10 @@ http://%HOSTIP:%HTTPPORT/0123456790123456790123456790123456790123456790123456790
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679/1295 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679: 300
Content-Length: 165
diff --git a/tests/data/test1296 b/tests/data/test1296
index 386eb18fc..55b01c4c4 100644
--- a/tests/data/test1296
+++ b/tests/data/test1296
@@ -41,13 +41,11 @@ http://user%0aname:password@%HOSTIP:%HTTPPORT/1296
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1296 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Basic dXNlcgpuYW1lOnBhc3N3b3Jk
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1297 b/tests/data/test1297
new file mode 100644
index 000000000..6cffff85d
--- /dev/null
+++ b/tests/data/test1297
@@ -0,0 +1,65 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+HTTP CONNECT
+HTTP proxy
+proxytunnel
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<connect>
+HTTP/1.1 200 Mighty fine indeed
+Server: test tunnel 2000
+
+</connect>
+
+<data nocheck="yes">
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+http-proxy
+</server>
+<name>
+CONNECT to peer that returns nothing
+</name>
+<command>
+--proxytunnel --proxy %HOSTIP:%PROXYPORT http://%HOSTIP.1297:%HTTPPORT/we/want/that/page/1297
+</command>
+<features>
+proxy
+</features>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<proxy>
+CONNECT %HOSTIP.1297:%HTTPPORT HTTP/1.1
+Host: %HOSTIP.1297:%HTTPPORT
+User-Agent: curl/%VERSION
+Proxy-Connection: Keep-Alive
+
+</proxy>
+<protocol>
+GET /we/want/that/page/1297 HTTP/1.1
+Host: %HOSTIP.1297:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+</protocol>
+# 52 - got nothing
+<errorcode>
+52
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/data/test1298 b/tests/data/test1298
index 061a4e1e0..6a34aa32b 100644
--- a/tests/data/test1298
+++ b/tests/data/test1298
@@ -42,12 +42,10 @@ HTTP GET special path with --request-target
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET XXX HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Testno: 1298
diff --git a/tests/data/test1299 b/tests/data/test1299
index 51e0e7983..2cf293a41 100644
--- a/tests/data/test1299
+++ b/tests/data/test1299
@@ -41,12 +41,10 @@ Send "OPTIONS *" with --request-target
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
OPTIONS * HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Testno: 1299
diff --git a/tests/data/test13 b/tests/data/test13
index 18f7f8114..121697947 100644
--- a/tests/data/test13
+++ b/tests/data/test13
@@ -31,12 +31,10 @@ http://%HOSTIP:%HTTPPORT/want/13 -X DELETE
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
DELETE /want/13 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1310 b/tests/data/test1310
index 9ffe0d586..cb9db8281 100644
--- a/tests/data/test1310
+++ b/tests/data/test1310
@@ -86,20 +86,17 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1310 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAwAAAA
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
GET /1310 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAADAAAAGAAYAE8AAAAYABgAZwAAAAAAAABAAAAACAAIAEAAAAAHAAcASAAAAAAAAAAAAAAAggEAAHRlc3R1c2VyVU5LTk9XTlpkQwKRCZFMhjj0tw47wEjKHRHlvzfxQamFcheMuv8v+xeqphEO5V41xRd7R9deOQ==
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1311 b/tests/data/test1311
index e47647c38..4078d7bb4 100644
--- a/tests/data/test1311
+++ b/tests/data/test1311
@@ -47,12 +47,10 @@ http://%HOSTIP:%HTTPPORT/1311 -J -O
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1311 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1312 b/tests/data/test1312
index bed492c16..54659b55b 100644
--- a/tests/data/test1312
+++ b/tests/data/test1312
@@ -47,12 +47,10 @@ CURL_TESTDIR=%PWD/log
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1312 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1313 b/tests/data/test1313
index 2331ae9ee..3d9c0940d 100644
--- a/tests/data/test1313
+++ b/tests/data/test1313
@@ -47,12 +47,10 @@ http://%HOSTIP:%HTTPPORT/1313 -J -O
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1313 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1314 b/tests/data/test1314
index 3963bd93f..55e3299e4 100644
--- a/tests/data/test1314
+++ b/tests/data/test1314
@@ -63,17 +63,16 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
GET http://firstplace.example.com/want/1314 HTTP/1.1
Host: firstplace.example.com
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://somewhere.example.com/reply/1314 HTTP/1.1
Host: somewhere.example.com
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1315 b/tests/data/test1315
index 888ddc5c1..ffc7bdc7b 100644
--- a/tests/data/test1315
+++ b/tests/data/test1315
@@ -40,12 +40,12 @@ dummy data
# Verify data after the test has been "shot"
<verify>
<strip>
-(^User-Agent:.*|-----+\w+)
+-----+\w+
</strip>
<protocol>
POST /we/want/1315 HTTP/1.1
-User-Agent: curl/7.18.2 (i686-pc-linux-gnu) libcurl/7.18.2 OpenSSL/0.9.7a ipv6 zlib/1.1.4
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 797
Content-Type: multipart/form-data; boundary=----------------------------9ef8d6205763
diff --git a/tests/data/test1317 b/tests/data/test1317
index d41886a5f..7964b10bd 100644
--- a/tests/data/test1317
+++ b/tests/data/test1317
@@ -43,12 +43,10 @@ HTTP with --resolve
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1317 HTTP/1.1
Host: example.com:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1318 b/tests/data/test1318
index dc182dccb..8ce468db1 100644
--- a/tests/data/test1318
+++ b/tests/data/test1318
@@ -43,16 +43,15 @@ HTTP with --resolve and same host name using different cases
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1318 HTTP/1.1
Host: MiXeDcAsE.cOm:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /13180001 HTTP/1.1
Host: mixedcase.com:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1319 b/tests/data/test1319
index 8fc968c89..b37a97055 100644
--- a/tests/data/test1319
+++ b/tests/data/test1319
@@ -63,9 +63,6 @@ pop3://pop.1319:%POP3PORT/1319 -p -x %HOSTIP:%PROXYPORT -u user:secret
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:
-</strip>
<protocol>
CAPA
USER user
@@ -76,7 +73,7 @@ QUIT
<proxy>
CONNECT pop.1319:%POP3PORT HTTP/1.1
Host: pop.1319:%POP3PORT
-User-Agent: curl/7.24.0-DEV (i686-pc-linux-gnu) libcurl/7.24.0-DEV OpenSSL/1.0.0e zlib/1.2.3.4 c-ares/1.7.6-DEV libidn/1.23 libssh2/1.4.0_DEV librtmp/2.2e
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
</proxy>
diff --git a/tests/data/test1320 b/tests/data/test1320
index da4079e93..2db0e3dee 100644
--- a/tests/data/test1320
+++ b/tests/data/test1320
@@ -46,9 +46,6 @@ smtp://smtp.1320:%SMTPPORT/1320 --mail-rcpt recipient@example.com --mail-from se
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
EHLO 1320
MAIL FROM:<sender@example.com>
@@ -66,7 +63,7 @@ body
<proxy>
CONNECT smtp.1320:%SMTPPORT HTTP/1.1
Host: smtp.1320:%SMTPPORT
-User-Agent: curl/7.24.0-DEV (i686-pc-linux-gnu) libcurl/7.24.0-DEV OpenSSL/1.0.0e zlib/1.2.3.4 c-ares/1.7.6-DEV libidn/1.23 libssh2/1.4.0_DEV librtmp/2.2e
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
</proxy>
diff --git a/tests/data/test1321 b/tests/data/test1321
index cc9117774..460779784 100644
--- a/tests/data/test1321
+++ b/tests/data/test1321
@@ -59,9 +59,6 @@ IMAP FETCH tunneled through HTTP proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
A001 CAPABILITY
A002 LOGIN user secret
@@ -72,7 +69,7 @@ A005 LOGOUT
<proxy>
CONNECT imap.1321:%IMAPPORT HTTP/1.1
Host: imap.1321:%IMAPPORT
-User-Agent: curl/7.24.0-DEV (i686-pc-linux-gnu) libcurl/7.24.0-DEV OpenSSL/1.0.0e zlib/1.2.3.4 c-ares/1.7.6-DEV libidn/1.23 libssh2/1.4.0_DEV librtmp/2.2e
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
</proxy>
diff --git a/tests/data/test1322 b/tests/data/test1322
index 974989517..71b8cb20e 100644
--- a/tests/data/test1322
+++ b/tests/data/test1322
@@ -44,12 +44,10 @@ HTTP with --resolve and hostname with trailing dot
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1322 HTTP/1.1
Host: example.com:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1324 b/tests/data/test1324
index d7e663a0f..0c89edbd1 100644
--- a/tests/data/test1324
+++ b/tests/data/test1324
@@ -43,12 +43,10 @@ HTTP with --resolve and [ipv6address]
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1324 HTTP/1.1
Host: example.com:%HTTP6PORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1325 b/tests/data/test1325
index 6da1cbc6a..bbf679df4 100644
--- a/tests/data/test1325
+++ b/tests/data/test1325
@@ -58,18 +58,17 @@ http://%HOSTIP:%HTTPPORT/we/1325 -L -d "moo"
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /we/1325 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 3
Content-Type: application/x-www-form-urlencoded
mooPOST /we/13250002 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 3
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test1328 b/tests/data/test1328
index 06088884a..0fd0c38de 100644
--- a/tests/data/test1328
+++ b/tests/data/test1328
@@ -54,16 +54,15 @@ HTTP GET a globbed range with -f
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /13280000 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /13280001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1331 b/tests/data/test1331
index 865abd969..09aabf879 100644
--- a/tests/data/test1331
+++ b/tests/data/test1331
@@ -71,18 +71,17 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://z.x.com/1331 HTTP/1.1
Host: z.x.com
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://z.x.com/1331 HTTP/1.1
Host: z.x.com
Proxy-Authorization: Basic bXluYW1lOm15cGFzc3dvcmQ=
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Cookie: proxycookie=weirdo
diff --git a/tests/data/test1332 b/tests/data/test1332
index 3447b2ddd..3271b5701 100644
--- a/tests/data/test1332
+++ b/tests/data/test1332
@@ -57,19 +57,17 @@ http://%HOSTIP:%HTTPPORT/blah/1332 -L -d "moo" --post303
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /blah/1332 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 3
Content-Type: application/x-www-form-urlencoded
mooPOST /blah/moo.html&testcase=/13320002 HTTP/1.1
-User-Agent: curl/7.10 (i686-pc-linux-gnu) libcurl/7.10 OpenSSL/0.9.6c ipv6 zlib/1.1.3
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 3
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test1333 b/tests/data/test1333
index 50ca42a29..3ef8ed49f 100644
--- a/tests/data/test1333
+++ b/tests/data/test1333
@@ -38,12 +38,10 @@ HTTP POST zero length, chunked-encoded
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
POST /1333 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Transfer-Encoding: chunked
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test1334 b/tests/data/test1334
index 59116e388..0885357fc 100644
--- a/tests/data/test1334
+++ b/tests/data/test1334
@@ -45,12 +45,10 @@ http://%HOSTIP:%HTTPPORT/1334 -O -D log/heads1334
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1334 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1335 b/tests/data/test1335
index bb499e73f..9cf1f3ef4 100644
--- a/tests/data/test1335
+++ b/tests/data/test1335
@@ -45,12 +45,10 @@ http://%HOSTIP:%HTTPPORT/1335 -O -D -
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1335 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1336 b/tests/data/test1336
index ebe562b6a..f6fcb9431 100644
--- a/tests/data/test1336
+++ b/tests/data/test1336
@@ -49,12 +49,10 @@ perl %SRCDIR/libtest/notexists.pl log/name1336
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1336 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1337 b/tests/data/test1337
index 80a99facf..d7f556cd3 100644
--- a/tests/data/test1337
+++ b/tests/data/test1337
@@ -49,12 +49,10 @@ perl %SRCDIR/libtest/notexists.pl log/name1337
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1337 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1338 b/tests/data/test1338
index d96f80467..8941a64a4 100644
--- a/tests/data/test1338
+++ b/tests/data/test1338
@@ -46,12 +46,10 @@ http://%HOSTIP:%HTTPPORT/1338 -J -O -D log/heads1338
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1338 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1339 b/tests/data/test1339
index a3c1f0e54..f08e87cdf 100644
--- a/tests/data/test1339
+++ b/tests/data/test1339
@@ -46,12 +46,10 @@ http://%HOSTIP:%HTTPPORT/1339 -J -O -D -
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1339 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1340 b/tests/data/test1340
index 644fb2b51..c2e065db2 100644
--- a/tests/data/test1340
+++ b/tests/data/test1340
@@ -47,12 +47,10 @@ http://%HOSTIP:%HTTPPORT/1340 -J -O -D log/heads1340 -w "curl: Saved to filename
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1340 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1341 b/tests/data/test1341
index ae226744c..060fc093d 100644
--- a/tests/data/test1341
+++ b/tests/data/test1341
@@ -47,12 +47,10 @@ http://%HOSTIP:%HTTPPORT/1341 -J -O -D - -w "curl: Saved to filename %{filename_
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1341 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1342 b/tests/data/test1342
index 1d7889d1e..012b63437 100644
--- a/tests/data/test1342
+++ b/tests/data/test1342
@@ -45,12 +45,10 @@ http://%HOSTIP:%HTTPPORT/1342 -i -O -D log/heads1342
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1342 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1343 b/tests/data/test1343
index a05cab04c..636afab24 100644
--- a/tests/data/test1343
+++ b/tests/data/test1343
@@ -45,12 +45,10 @@ http://%HOSTIP:%HTTPPORT/1343 -i -O -D -
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1343 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1344 b/tests/data/test1344
index ac354f0dd..4d8bd4aff 100644
--- a/tests/data/test1344
+++ b/tests/data/test1344
@@ -49,12 +49,10 @@ perl %SRCDIR/libtest/notexists.pl log/name1344
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1344 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1345 b/tests/data/test1345
index 6d1201e16..f69a56adf 100644
--- a/tests/data/test1345
+++ b/tests/data/test1345
@@ -49,12 +49,10 @@ perl %SRCDIR/libtest/notexists.pl log/name1345
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1345 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1346 b/tests/data/test1346
index 347214e69..83cdaa8c4 100644
--- a/tests/data/test1346
+++ b/tests/data/test1346
@@ -45,12 +45,10 @@ http://%HOSTIP:%HTTPPORT/1346 -i -O
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1346 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1347 b/tests/data/test1347
index 8eac42cb2..f16abcd02 100644
--- a/tests/data/test1347
+++ b/tests/data/test1347
@@ -49,12 +49,10 @@ perl %SRCDIR/libtest/notexists.pl log/name1347
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1347 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1364 b/tests/data/test1364
index e8c981d77..777d9b248 100644
--- a/tests/data/test1364
+++ b/tests/data/test1364
@@ -40,12 +40,10 @@ perl %SRCDIR/libtest/notexists.pl log/1364
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1364 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1365 b/tests/data/test1365
index 4a09cfd6a..c69ee4b7c 100644
--- a/tests/data/test1365
+++ b/tests/data/test1365
@@ -40,12 +40,10 @@ perl %SRCDIR/libtest/notexists.pl log/1365
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1365 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1366 b/tests/data/test1366
index 62e3b0c42..c87455fc0 100644
--- a/tests/data/test1366
+++ b/tests/data/test1366
@@ -41,12 +41,10 @@ perl %SRCDIR/libtest/notexists.pl log/1366 log/name1366
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1366 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1367 b/tests/data/test1367
index d4bd3d777..68bc33363 100644
--- a/tests/data/test1367
+++ b/tests/data/test1367
@@ -41,12 +41,10 @@ perl %SRCDIR/libtest/notexists.pl log/1367 log/name1367
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1367 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1368 b/tests/data/test1368
index 6a926ab68..37805176b 100644
--- a/tests/data/test1368
+++ b/tests/data/test1368
@@ -41,12 +41,10 @@ perl %SRCDIR/libtest/notexists.pl log/1368
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1368 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1369 b/tests/data/test1369
index 5176ed0b0..1a5944633 100644
--- a/tests/data/test1369
+++ b/tests/data/test1369
@@ -41,12 +41,10 @@ perl %SRCDIR/libtest/notexists.pl log/1369
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1369 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1370 b/tests/data/test1370
index d0abbdd68..ec5e7b54c 100644
--- a/tests/data/test1370
+++ b/tests/data/test1370
@@ -42,12 +42,10 @@ perl %SRCDIR/libtest/notexists.pl log/1370 log/name1370
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1370 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1371 b/tests/data/test1371
index fe3977fae..d3e187adc 100644
--- a/tests/data/test1371
+++ b/tests/data/test1371
@@ -42,12 +42,10 @@ perl %SRCDIR/libtest/notexists.pl log/1371 log/name1371
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1371 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1372 b/tests/data/test1372
index a2b8ec961..49c89f96f 100644
--- a/tests/data/test1372
+++ b/tests/data/test1372
@@ -40,12 +40,10 @@ perl %SRCDIR/libtest/notexists.pl log/1372
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1372 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1373 b/tests/data/test1373
index ae906d7bd..3ceaacaf9 100644
--- a/tests/data/test1373
+++ b/tests/data/test1373
@@ -40,12 +40,10 @@ perl %SRCDIR/libtest/notexists.pl log/1373
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1373 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1374 b/tests/data/test1374
index f8d9d0dd0..e143b41db 100644
--- a/tests/data/test1374
+++ b/tests/data/test1374
@@ -41,12 +41,10 @@ perl %SRCDIR/libtest/notexists.pl log/1374 log/name1374
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1374 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1375 b/tests/data/test1375
index 595f03ac1..f6219a1ea 100644
--- a/tests/data/test1375
+++ b/tests/data/test1375
@@ -41,12 +41,10 @@ perl %SRCDIR/libtest/notexists.pl log/1375 log/name1375
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1375 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1376 b/tests/data/test1376
index f34c27745..1d12c4c6a 100644
--- a/tests/data/test1376
+++ b/tests/data/test1376
@@ -40,12 +40,10 @@ perl %SRCDIR/libtest/notexists.pl log/1376
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1376 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1377 b/tests/data/test1377
index f542b11c7..f24561654 100644
--- a/tests/data/test1377
+++ b/tests/data/test1377
@@ -41,12 +41,10 @@ perl %SRCDIR/libtest/notexists.pl log/1377 log/name1377
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1377 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test138 b/tests/data/test138
index 4eb73e6cf..873313848 100644
--- a/tests/data/test138
+++ b/tests/data/test138
@@ -15,6 +15,7 @@ this is file contents
</size>
<servercmd>
RETRNOSIZE
+REPLY SIZE 500 command not understood
</servercmd>
</reply>
diff --git a/tests/data/test14 b/tests/data/test14
index 21a4865b4..f6c568ede 100644
--- a/tests/data/test14
+++ b/tests/data/test14
@@ -30,13 +30,10 @@ http://%HOSTIP:%HTTPPORT/want/14 -i --head
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
HEAD /want/14 HTTP/1.1
-User-Agent: curl/7.4.2-pre4 (sparc-sun-solaris2.7) libcurl 7.4.2-pre4
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1400 b/tests/data/test1400
index 9f6bd47a2..5a910d19b 100644
--- a/tests/data/test1400
+++ b/tests/data/test1400
@@ -37,13 +37,10 @@ http://%HOSTIP:%HTTPPORT/we/want/1400 --libcurl log/test1400.c
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/1400 HTTP/1.1
-User-Agent: curl/7.18.2 (i686-pc-linux-gnu) libcurl/7.18.2 OpenSSL/0.9.7a ipv6 zlib/1.1.4
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
@@ -61,7 +58,7 @@ $_ = '' if /CURLOPT_INTERLEAVEDATA/
<file name="log/test1400.c" mode="text">
/********* Sample code generated by the curl command line tool **********
* All curl_easy_setopt() options are documented at:
- * https://curl.haxx.se/libcurl/c/curl_easy_setopt.html
+ * https://curl.se/libcurl/c/curl_easy_setopt.html
************************************************************************/
#include <gnurl/curl.h>
@@ -76,6 +73,7 @@ int main(int argc, char *argv[])
curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped");
curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
/* Here is a list of options the curl code used that cannot get generated
diff --git a/tests/data/test1401 b/tests/data/test1401
index c414c4751..ad3f0c8d0 100644
--- a/tests/data/test1401
+++ b/tests/data/test1401
@@ -41,14 +41,11 @@ http://%HOSTIP:%HTTPPORT/we/want/1401 --libcurl log/test1401.c --basic -u fake:u
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/1401 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
-User-Agent: stripped
Authorization: Basic ZmFrZTp1c2Vy
+User-Agent: MyUA
Accept: */*
Cookie: chocolate=chip
X-Files: Mulder
@@ -66,7 +63,7 @@ $_ = '' if /CURLOPT_INTERLEAVEDATA/
<file name="log/test1401.c" mode="text">
/********* Sample code generated by the curl command line tool **********
* All curl_easy_setopt() options are documented at:
- * https://curl.haxx.se/libcurl/c/curl_easy_setopt.html
+ * https://curl.se/libcurl/c/curl_easy_setopt.html
************************************************************************/
#include <gnurl/curl.h>
@@ -90,6 +87,7 @@ int main(int argc, char *argv[])
curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
curl_easy_setopt(hnd, CURLOPT_COOKIE, "chocolate=chip");
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
curl_easy_setopt(hnd, CURLOPT_PROTOCOLS, (long)CURLPROTO_FILE |
(long)CURLPROTO_FTP |
diff --git a/tests/data/test1402 b/tests/data/test1402
index 56861a4ba..40ac50af8 100644
--- a/tests/data/test1402
+++ b/tests/data/test1402
@@ -38,13 +38,10 @@ http://%HOSTIP:%HTTPPORT/we/want/1402 --libcurl log/test1402.c -d "foo=bar" -d "
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /we/want/1402 HTTP/1.1
-User-Agent: curl/7.18.2 (i686-pc-linux-gnu) libcurl/7.18.2 OpenSSL/0.9.7a ipv6 zlib/1.1.4
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 16
Content-Type: application/x-www-form-urlencoded
@@ -64,7 +61,7 @@ $_ = '' if /CURLOPT_INTERLEAVEDATA/
<file name="log/test1402.c" mode="text">
/********* Sample code generated by the curl command line tool **********
* All curl_easy_setopt() options are documented at:
- * https://curl.haxx.se/libcurl/c/curl_easy_setopt.html
+ * https://curl.se/libcurl/c/curl_easy_setopt.html
************************************************************************/
#include <gnurl/curl.h>
@@ -81,6 +78,7 @@ int main(int argc, char *argv[])
curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped");
curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
/* Here is a list of options the curl code used that cannot get generated
diff --git a/tests/data/test1403 b/tests/data/test1403
index 4237c07c8..c77f37fbf 100644
--- a/tests/data/test1403
+++ b/tests/data/test1403
@@ -38,13 +38,10 @@ http://%HOSTIP:%HTTPPORT/we/want/1403 --libcurl log/test1403.c -G -d "foo=bar" -
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/1403?foo=bar&baz=quux HTTP/1.1
-User-Agent: curl/7.18.2 (i686-pc-linux-gnu) libcurl/7.18.2 OpenSSL/0.9.7a ipv6 zlib/1.1.4
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
@@ -61,7 +58,7 @@ $_ = '' if /CURLOPT_INTERLEAVEDATA/
<file name="log/test1403.c" mode="text">
/********* Sample code generated by the curl command line tool **********
* All curl_easy_setopt() options are documented at:
- * https://curl.haxx.se/libcurl/c/curl_easy_setopt.html
+ * https://curl.se/libcurl/c/curl_easy_setopt.html
************************************************************************/
#include <gnurl/curl.h>
@@ -76,6 +73,7 @@ int main(int argc, char *argv[])
curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped");
curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
/* Here is a list of options the curl code used that cannot get generated
diff --git a/tests/data/test1404 b/tests/data/test1404
index 35e1ee91b..93ab07cac 100644
--- a/tests/data/test1404
+++ b/tests/data/test1404
@@ -44,12 +44,12 @@ dummy data
# Verify data after the test has been "shot"
<verify>
<strip>
-(^User-Agent:.*|-----+\w+)
+-----+\w+
</strip>
<protocol>
POST /we/want/1404 HTTP/1.1
-User-Agent: curl/7.18.2 (i686-pc-linux-gnu) libcurl/7.18.2 OpenSSL/0.9.7a ipv6 zlib/1.1.4
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 882
Content-Type: multipart/form-data; boundary=----------------------------9ef8d6205763
@@ -101,7 +101,7 @@ $_ = '' if /\/\* "value" \*\//
<file name="log/test1404.c" mode="text">
/********* Sample code generated by the curl command line tool **********
* All curl_easy_setopt() options are documented at:
- * https://curl.haxx.se/libcurl/c/curl_easy_setopt.html
+ * https://curl.se/libcurl/c/curl_easy_setopt.html
************************************************************************/
#include <gnurl/curl.h>
@@ -147,6 +147,7 @@ int main(int argc, char *argv[])
curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped");
curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
/* Here is a list of options the curl code used that cannot get generated
diff --git a/tests/data/test1405 b/tests/data/test1405
index a1902bb72..629dd2e5c 100644
--- a/tests/data/test1405
+++ b/tests/data/test1405
@@ -61,7 +61,7 @@ QUIT
<file name="log/test1405.c" mode="text">
/********* Sample code generated by the curl command line tool **********
* All curl_easy_setopt() options are documented at:
- * https://curl.haxx.se/libcurl/c/curl_easy_setopt.html
+ * https://curl.se/libcurl/c/curl_easy_setopt.html
************************************************************************/
#include <gnurl/curl.h>
@@ -89,6 +89,7 @@ int main(int argc, char *argv[])
curl_easy_setopt(hnd, CURLOPT_POSTQUOTE, slist2);
curl_easy_setopt(hnd, CURLOPT_PREQUOTE, slist3);
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
/* Here is a list of options the curl code used that cannot get generated
diff --git a/tests/data/test1406 b/tests/data/test1406
index dc8247dfa..185eea407 100644
--- a/tests/data/test1406
+++ b/tests/data/test1406
@@ -60,7 +60,7 @@ body
<file name="log/test1406.c" mode="text">
/********* Sample code generated by the curl command line tool **********
* All curl_easy_setopt() options are documented at:
- * https://curl.haxx.se/libcurl/c/curl_easy_setopt.html
+ * https://curl.se/libcurl/c/curl_easy_setopt.html
************************************************************************/
#include <gnurl/curl.h>
@@ -79,6 +79,7 @@ int main(int argc, char *argv[])
curl_easy_setopt(hnd, CURLOPT_URL, "smtp://%HOSTIP:%SMTPPORT/1406");
curl_easy_setopt(hnd, CURLOPT_UPLOAD, 1L);
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
curl_easy_setopt(hnd, CURLOPT_MAIL_FROM, "sender@example.com");
curl_easy_setopt(hnd, CURLOPT_MAIL_RCPT, slist1);
diff --git a/tests/data/test1407 b/tests/data/test1407
index bc25cebfb..1a50de75e 100644
--- a/tests/data/test1407
+++ b/tests/data/test1407
@@ -47,7 +47,7 @@ QUIT
<file name="log/test1407.c" mode="text">
/********* Sample code generated by the curl command line tool **********
* All curl_easy_setopt() options are documented at:
- * https://curl.haxx.se/libcurl/c/curl_easy_setopt.html
+ * https://curl.se/libcurl/c/curl_easy_setopt.html
************************************************************************/
#include <gnurl/curl.h>
@@ -62,6 +62,7 @@ int main(int argc, char *argv[])
curl_easy_setopt(hnd, CURLOPT_DIRLISTONLY, 1L);
curl_easy_setopt(hnd, CURLOPT_USERPWD, "user:secret");
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
/* Here is a list of options the curl code used that cannot get generated
diff --git a/tests/data/test1408 b/tests/data/test1408
index bf775ed39..6d3131fb6 100644
--- a/tests/data/test1408
+++ b/tests/data/test1408
@@ -55,16 +55,15 @@ HTTP receive cookies over IPV6
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /path/14080001 HTTP/1.1
Host: %HOST6IP:%HTTP6PORT
+User-Agent: curl/%VERSION
Accept: */*
GET /path/14080002 HTTP/1.1
Host: %HOST6IP:%HTTP6PORT
+User-Agent: curl/%VERSION
Accept: */*
Cookie: time=1
diff --git a/tests/data/test1411 b/tests/data/test1411
index 3ffd586de..93e3b4b8b 100644
--- a/tests/data/test1411
+++ b/tests/data/test1411
@@ -46,12 +46,10 @@ http://%HOSTIP:%HTTPPORT/1411 -T log/empty1411
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /1411 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 0
diff --git a/tests/data/test1412 b/tests/data/test1412
index 36d3d1d93..808ed17f2 100644
--- a/tests/data/test1412
+++ b/tests/data/test1412
@@ -106,29 +106,27 @@ four is the number of lines
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1412 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /1412 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="gimme all yer s3cr3ts", nonce="11223344", uri="/1412", response="0390dbe89e31adca0413d11f91f30e7f"
-User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
GET /14120001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
-User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
GET /14120001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="gimme all yer s3cr3ts", nonce="11223344", uri="/14120001", response="0085df91870374c8bf4e94415e7fbf8e"
-User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1413 b/tests/data/test1413
index 6e889a8a2..96467f169 100644
--- a/tests/data/test1413
+++ b/tests/data/test1413
@@ -56,16 +56,15 @@ http://%HOSTIP:%HTTPPORT/this/1413 -L
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /this/1413 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /this/moo.html/14130002 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1415 b/tests/data/test1415
index 94ce02c59..4519f3899 100644
--- a/tests/data/test1415
+++ b/tests/data/test1415
@@ -53,12 +53,10 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://example.com/we/want/1415 HTTP/1.1
Host: example.com
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
@@ -66,7 +64,7 @@ Proxy-Connection: Keep-Alive
<file name="log/jar1415.txt" mode="text">
# Netscape HTTP Cookie File
-# https://curl.haxx.se/docs/http-cookies.html
+# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
.example.com TRUE / FALSE 2145830400 test7value test7
diff --git a/tests/data/test1416 b/tests/data/test1416
index 546575e5d..f6e9bbfe4 100644
--- a/tests/data/test1416
+++ b/tests/data/test1416
@@ -44,12 +44,10 @@ http://%HOSTIP:%HTTPPORT/1416
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1416 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1417 b/tests/data/test1417
index 4d3971ea8..a141b11d2 100644
--- a/tests/data/test1417
+++ b/tests/data/test1417
@@ -56,12 +56,10 @@ http://%HOSTIP:%HTTPPORT/1417 -D log/heads1417
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1417 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1418 b/tests/data/test1418
index c137b1c59..51d2e5f0a 100644
--- a/tests/data/test1418
+++ b/tests/data/test1418
@@ -93,26 +93,27 @@ http://%HOSTIP:%HTTPPORT/1418 -u testuser:testpass --anyauth http://%HOSTIP:%HTT
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1418 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /1418 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="loonie", nonce="314156592", uri="/1418", response="986238b7e0077754944c966f56d9bc77"
+User-Agent: curl/%VERSION
Accept: */*
GET /14180003 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /14180003 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="loonie", nonce="314156592", uri="/14180003", response="1c6390a67bac3283a9b023402f3b3540"
+User-Agent: curl/%VERSION
Accept: */*
[DISCONNECT]
diff --git a/tests/data/test1419 b/tests/data/test1419
index f29ce4444..6d05f0b5a 100644
--- a/tests/data/test1419
+++ b/tests/data/test1419
@@ -51,16 +51,15 @@ http://%HOSTIP:%HTTPPORT/1419 --anyauth http://%HOSTIP:%HTTPPORT/14190003
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1419 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /14190003 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
[DISCONNECT]
diff --git a/tests/data/test1420 b/tests/data/test1420
index 99d50c35b..0dcf91314 100644
--- a/tests/data/test1420
+++ b/tests/data/test1420
@@ -53,7 +53,7 @@ A005 LOGOUT
<file name="log/test1420.c" mode="text">
/********* Sample code generated by the curl command line tool **********
* All curl_easy_setopt() options are documented at:
- * https://curl.haxx.se/libcurl/c/curl_easy_setopt.html
+ * https://curl.se/libcurl/c/curl_easy_setopt.html
************************************************************************/
#include <gnurl/curl.h>
@@ -67,6 +67,7 @@ int main(int argc, char *argv[])
curl_easy_setopt(hnd, CURLOPT_URL, "imap://%HOSTIP:%IMAPPORT/1420/;MAILINDEX=1");
curl_easy_setopt(hnd, CURLOPT_USERPWD, "user:secret");
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
/* Here is a list of options the curl code used that cannot get generated
diff --git a/tests/data/test1421 b/tests/data/test1421
index dea49e781..c219770e3 100644
--- a/tests/data/test1421
+++ b/tests/data/test1421
@@ -55,17 +55,16 @@ Content-Length: 6
-foo-
</stdout>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://test.remote.haxx.se.1421:8990/ HTTP/1.1
Host: test.remote.haxx.se.1421:8990
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://different.remote.haxx.se.1421:8990/ HTTP/1.1
Host: different.remote.haxx.se.1421:8990
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1422 b/tests/data/test1422
index cbb2d63bc..4108091f4 100644
--- a/tests/data/test1422
+++ b/tests/data/test1422
@@ -47,12 +47,10 @@ http://%HOSTIP:%HTTPPORT/1422 -J -O file://%PWD/log/name1422
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1422 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1423 b/tests/data/test1423
index 908ff8c29..b0fcef3ba 100644
--- a/tests/data/test1423
+++ b/tests/data/test1423
@@ -40,12 +40,10 @@ perl %SRCDIR/libtest/notexists.pl log/1423
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1423 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1424 b/tests/data/test1424
index 17bc46a1d..8f922e620 100644
--- a/tests/data/test1424
+++ b/tests/data/test1424
@@ -57,12 +57,10 @@ http://%HOSTIP:%HTTPPORT/1424 -z "dec 12 11:00:00 1999 GMT" -o log/outfile1424
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1424 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
If-Modified-Since: Sun, 12 Dec 1999 11:00:00 GMT
diff --git a/tests/data/test1425 b/tests/data/test1425
index ce9ba97fb..7122cd637 100644
--- a/tests/data/test1425
+++ b/tests/data/test1425
Binary files differ
diff --git a/tests/data/test1426 b/tests/data/test1426
index 851d8c3fb..1344b8ebd 100644
--- a/tests/data/test1426
+++ b/tests/data/test1426
Binary files differ
diff --git a/tests/data/test1428 b/tests/data/test1428
index f09c02dd9..0ff74d4be 100644
--- a/tests/data/test1428
+++ b/tests/data/test1428
@@ -60,13 +60,10 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<proxy>
CONNECT test.1428:%HTTPPORT HTTP/1.1
Host: test.1428:%HTTPPORT
-User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
header-type: proxy
@@ -75,7 +72,7 @@ header-type: proxy
GET /we/want/that/page/1428 HTTP/1.1
Host: test.1428:%HTTPPORT
Authorization: Basic aWFtOm15OjtzZWxm
-User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
header-type: server
diff --git a/tests/data/test1429 b/tests/data/test1429
index b6a66c75f..4f3989cf5 100644
--- a/tests/data/test1429
+++ b/tests/data/test1429
@@ -57,12 +57,10 @@ Funny-head: yesyes
-foo-
234
</stdout>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1429 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1430 b/tests/data/test1430
index e3c9b1d60..5acc7f12e 100644
--- a/tests/data/test1430
+++ b/tests/data/test1430
@@ -40,12 +40,10 @@ http://%HOSTIP:%HTTPPORT/1430
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1430 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1431 b/tests/data/test1431
index bec3ebbde..58500879c 100644
--- a/tests/data/test1431
+++ b/tests/data/test1431
@@ -40,12 +40,10 @@ http://%HOSTIP:%HTTPPORT/1431
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1431 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1432 b/tests/data/test1432
index 7f41c65be..fadbe8385 100644
--- a/tests/data/test1432
+++ b/tests/data/test1432
@@ -41,12 +41,10 @@ http://%HOSTIP:%HTTPPORT/1432
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1432 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1433 b/tests/data/test1433
index a159daff3..6656114d5 100644
--- a/tests/data/test1433
+++ b/tests/data/test1433
@@ -41,12 +41,10 @@ http://%HOSTIP:%HTTPPORT/1433
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1433 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1434 b/tests/data/test1434
index 0b33bb958..55031be71 100644
--- a/tests/data/test1434
+++ b/tests/data/test1434
@@ -76,13 +76,11 @@ http://%HOSTIP:%HTTPPORT/1434 -C 100
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1434 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Range: bytes=100-
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1435 b/tests/data/test1435
index bd171a453..73262498e 100644
--- a/tests/data/test1435
+++ b/tests/data/test1435
@@ -33,12 +33,10 @@ simple HTTP GET over Unix socket
</client>
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1435 HTTP/1.1
Host: server-interpreted.example.com
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1436 b/tests/data/test1436
index e40a3bf4b..040b3b389 100644
--- a/tests/data/test1436
+++ b/tests/data/test1436
@@ -47,20 +47,20 @@ HTTP requests with multiple connections over Unix socket
</client>
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /14360001 HTTP/1.1
Host: one.example.com
+User-Agent: curl/%VERSION
Accept: */*
GET /14360002 HTTP/1.1
Host: two.example.com
+User-Agent: curl/%VERSION
Accept: */*
GET /14360003 HTTP/1.1
Host: one.example.com
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1437 b/tests/data/test1437
index 6a48444fb..07346a9e8 100644
--- a/tests/data/test1437
+++ b/tests/data/test1437
@@ -65,18 +65,16 @@ http://%HOSTIP:%HTTPPORT/1437 -u testuser:testpass --digest
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1437 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /1437 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="testrealm", nonce="2", uri="/1437", response="4376eb639bf8e7343a6e7b56e1b89c4f", algorithm=MD5
-User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1438 b/tests/data/test1438
index 8aaedb71e..14818829e 100644
--- a/tests/data/test1438
+++ b/tests/data/test1438
@@ -48,11 +48,9 @@ HTTP
<protocol>
GET /1438 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
-<strip>
-^User-Agent:.*
-</strip>
</verify>
</testcase>
diff --git a/tests/data/test1439 b/tests/data/test1439
index cb906adbc..a76ccf002 100644
--- a/tests/data/test1439
+++ b/tests/data/test1439
@@ -26,7 +26,7 @@ http
</server>
<name>
-Check if %{scheme} returns HTTP
+Check if %{http_version} returns 1.1
</name>
<command>
http://%HOSTIP:%HTTPPORT/1439 --write-out '%{http_version}'
@@ -48,11 +48,9 @@ testdata
<protocol>
GET /1439 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
-<strip>
-^User-Agent:.*
-</strip>
</verify>
</testcase>
diff --git a/tests/data/test1443 b/tests/data/test1443
index 696886706..7da739e54 100644
--- a/tests/data/test1443
+++ b/tests/data/test1443
@@ -52,12 +52,10 @@ perl -e 'exit((stat("log/1443"))[9] != 960898200)'
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1443 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1448 b/tests/data/test1448
index 87ffed60d..38c022756 100644
--- a/tests/data/test1448
+++ b/tests/data/test1448
@@ -59,16 +59,15 @@ http://åäö.se:%HTTPPORT/1448 --resolve xn--4cab6c.se:%HTTPPORT:%HOSTIP -L --c
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1448 HTTP/1.1
Host: xn--4cab6c.se:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /14480001 HTTP/1.1
Host: xn--4cab6c.se:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1455 b/tests/data/test1455
index 8483d7bb8..b8a864f81 100644
--- a/tests/data/test1455
+++ b/tests/data/test1455
@@ -47,9 +47,6 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<strippart>
s/^PROXY TCP4 %CLIENTIP %HOSTIP (\d*) %HTTPPORT/proxy-line/
</strippart>
@@ -57,6 +54,7 @@ s/^PROXY TCP4 %CLIENTIP %HOSTIP (\d*) %HTTPPORT/proxy-line/
proxy-line
GET /1455 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Testno: 1455
diff --git a/tests/data/test1456 b/tests/data/test1456
index 16a78b2af..59e073918 100644
--- a/tests/data/test1456
+++ b/tests/data/test1456
@@ -50,10 +50,6 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:
-</strip>
-
# Strip off the (random) local port number. This test used to use a fixed
# local port number that frequently causes the test to fail
<strippart>
@@ -63,6 +59,7 @@ s/PROXY TCP6 ::1 ::1 (\d+) (\d+)/PROXY TCP6 ::1 ::1 $2/
PROXY TCP6 ::1 ::1 %HTTP6PORT
GET /1456 HTTP/1.1
Host: %HOST6IP:%HTTP6PORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1457 b/tests/data/test1457
index 575748f46..ab447ac54 100644
--- a/tests/data/test1457
+++ b/tests/data/test1457
@@ -51,11 +51,9 @@ line2
<protocol>
GET /1457 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
-<strip>
-^User-Agent:.*
-</strip>
</verify>
</testcase>
diff --git a/tests/data/test1458 b/tests/data/test1458
index 072e43ce9..c4f25f57e 100644
--- a/tests/data/test1458
+++ b/tests/data/test1458
@@ -43,12 +43,10 @@ HTTP with wildcard --resolve
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1458 HTTP/1.1
Host: example.com:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1460 b/tests/data/test1460
index d7b30c5e8..1cc13353e 100644
--- a/tests/data/test1460
+++ b/tests/data/test1460
@@ -47,9 +47,6 @@ initial content
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
# Warning: --include and --remote-header-name cannot be combined.
<errorcode>
2
diff --git a/tests/data/test1461 b/tests/data/test1461
new file mode 100644
index 000000000..4b8f6c410
--- /dev/null
+++ b/tests/data/test1461
@@ -0,0 +1,53 @@
+<testcase>
+<info>
+<keywords>
+--help
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+none
+</server>
+ <name>
+curl important --help
+ </name>
+ <command>
+--help
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<errorcode>
+0
+</errorcode>
+<stdout mode="text">
+Usage: curl [options...] <url>
+ -d, --data <data> HTTP POST data
+ -f, --fail Fail silently (no output at all) on HTTP errors
+ -h, --help <category> Get help for commands
+ -i, --include Include protocol response headers in the output
+ -o, --output <file> Write to file instead of stdout
+ -O, --remote-name Write output to a file named as the remote file
+ -s, --silent Silent mode
+ -T, --upload-file <file> Transfer local FILE to destination
+ -u, --user <user:password> Server user and password
+ -A, --user-agent <name> Send User-Agent <name> to server
+ -v, --verbose Make the operation more talkative
+ -V, --version Show version number and quit
+
+This is not the full help, this menu is stripped into categories.
+Use "--help category" to get an overview of all categories.
+For all options use the manual or "--help all".
+</stdout>
+</verify>
+</testcase>
diff --git a/tests/data/test1462 b/tests/data/test1462
new file mode 100644
index 000000000..ce9902946
--- /dev/null
+++ b/tests/data/test1462
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+--help
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+none
+</server>
+ <name>
+curl invalid category --help
+ </name>
+ <command>
+--help sdfafdsfadsfsd
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<errorcode>
+0
+</errorcode>
+<stdout mode="text">
+Usage: curl [options...] <url>
+Invalid category provided, here is a list of all categories:
+
+ auth Different types of authentication methods
+ connection Low level networking operations
+ curl The command line tool itself
+ dns General DNS options
+ file FILE protocol options
+ ftp FTP protocol options
+ http HTTP and HTTPS protocol options
+ imap IMAP protocol options
+ misc Options that don't fit into any other category
+ output Filesystem output
+ pop3 POP3 protocol options
+ post HTTP Post specific options
+ proxy All options related to proxies
+ scp SCP protocol options
+ sftp SFTP protocol options
+ smtp SMTP protocol options
+ ssh SSH protocol options
+ telnet TELNET protocol options
+ tftp TFTP protocol options
+ tls All TLS/SSL related options
+ upload All options for uploads
+ verbose Options related to any kind of command line output of curl
+</stdout>
+</verify>
+</testcase>
diff --git a/tests/data/test1463 b/tests/data/test1463
new file mode 100644
index 000000000..7e1fe9b84
--- /dev/null
+++ b/tests/data/test1463
@@ -0,0 +1,44 @@
+<testcase>
+<info>
+<keywords>
+FILE
+--help
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+none
+</server>
+<features>
+file
+</features>
+ <name>
+curl file category --help
+ </name>
+ <command>
+--help file
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<errorcode>
+0
+</errorcode>
+<stdout mode="text">
+Usage: curl [options...] <url>
+file: FILE protocol options
+ -I, --head Show document info only
+ -r, --range <range> Retrieve only the bytes within RANGE
+</stdout>
+</verify>
+</testcase>
diff --git a/tests/data/test1464 b/tests/data/test1464
new file mode 100644
index 000000000..167e80d6d
--- /dev/null
+++ b/tests/data/test1464
@@ -0,0 +1,44 @@
+<testcase>
+<info>
+<keywords>
+FILE
+--help
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+none
+</server>
+<features>
+file
+</features>
+ <name>
+curl file category --help with lower/upper mix
+ </name>
+ <command>
+--help fIlE
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<errorcode>
+0
+</errorcode>
+<stdout mode="text">
+Usage: curl [options...] <url>
+file: FILE protocol options
+ -I, --head Show document info only
+ -r, --range <range> Retrieve only the bytes within RANGE
+</stdout>
+</verify>
+</testcase>
diff --git a/tests/data/test1465 b/tests/data/test1465
new file mode 100644
index 000000000..4da25dc92
--- /dev/null
+++ b/tests/data/test1465
Binary files differ
diff --git a/tests/data/test15 b/tests/data/test15
index 3b1fa4369..a82fa0cf6 100644
--- a/tests/data/test15
+++ b/tests/data/test15
@@ -44,12 +44,10 @@ Content-Length: 26
Repeated nonsense-headers
http://%HOSTIP:%HTTPPORT/want/15 200 26
</stdout>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/15 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test150 b/tests/data/test150
index e9fde393b..2179163de 100644
--- a/tests/data/test150
+++ b/tests/data/test150
@@ -83,20 +83,17 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /150 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
GET /150 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAADj3hs3u3j0kgJqCrLM+74BmaoNHDfIJjHRlc3R1c2VyY3VybGhvc3Q=
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1502 b/tests/data/test1502
index 4c084d644..9e7bcf257 100644
--- a/tests/data/test1502
+++ b/tests/data/test1502
@@ -45,9 +45,6 @@ http://google.com:%HTTPPORT/1502 %HTTPPORT %HOSTIP
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1502 HTTP/1.1
Host: google.com:%HTTPPORT
diff --git a/tests/data/test1503 b/tests/data/test1503
index 8665de60c..288639463 100644
--- a/tests/data/test1503
+++ b/tests/data/test1503
@@ -45,9 +45,6 @@ http://google.com:%HTTPPORT/1503 %HTTPPORT %HOSTIP
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1503 HTTP/1.1
Host: google.com:%HTTPPORT
diff --git a/tests/data/test1504 b/tests/data/test1504
index b8463c526..5ca66076e 100644
--- a/tests/data/test1504
+++ b/tests/data/test1504
@@ -45,9 +45,6 @@ http://google.com:%HTTPPORT/1504 %HTTPPORT %HOSTIP
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1504 HTTP/1.1
Host: google.com:%HTTPPORT
diff --git a/tests/data/test1505 b/tests/data/test1505
index c6e5a7ca1..14e1141d4 100644
--- a/tests/data/test1505
+++ b/tests/data/test1505
@@ -45,9 +45,6 @@ http://google.com:%HTTPPORT/1505 %HTTPPORT %HOSTIP
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1505 HTTP/1.1
Host: google.com:%HTTPPORT
diff --git a/tests/data/test151 b/tests/data/test151
index 8f20d1d8b..03a55b4dc 100644
--- a/tests/data/test151
+++ b/tests/data/test151
@@ -34,13 +34,10 @@ http://%HOSTIP:%HTTPPORT/151
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
GET /151 HTTP/1.1
-User-Agent: curl/7.8.1-pre3 (sparc-sun-solaris2.7) libcurl 7.8.1-pre3 (OpenSSL 0.9.6a) (krb4 enabled)
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test152 b/tests/data/test152
index 2cc521614..2c48b0379 100644
--- a/tests/data/test152
+++ b/tests/data/test152
@@ -35,13 +35,10 @@ http://%HOSTIP:%HTTPPORT/152 --fail
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
GET /152 HTTP/1.1
-User-Agent: curl/7.8.1-pre3 (sparc-sun-solaris2.7) libcurl 7.8.1-pre3 (OpenSSL 0.9.6a) (krb4 enabled)
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1524 b/tests/data/test1524
index ed0c0476e..349054020 100644
--- a/tests/data/test1524
+++ b/tests/data/test1524
@@ -55,20 +55,18 @@ moo
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
PUT /blah/1524 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 4
Expect: 100-continue
moo
GET /blah/moo.html&testcase=/15240002 HTTP/1.1
-User-Agent: this should be ignored
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
diff --git a/tests/data/test153 b/tests/data/test153
index 1f55f39b6..a582595ac 100644
--- a/tests/data/test153
+++ b/tests/data/test153
@@ -89,34 +89,34 @@ http://%HOSTIP:%HTTPPORT/1530001 -u testuser:testpass --digest http://%HOSTIP:%H
<verify>
<strip>
^Authorization.*cnonce
-^User-Agent:.*
</strip>
<protocol>
GET /1530001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /1530001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="testrealm", nonce="1053604145", uri="/1530001", response="f4f83139396995bac665f24a1f1055c7"
-User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
GET /1530002 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
-User-Agent: curl/7.11.0-CVS (i686-pc-linux-gnu) libcurl/7.11.0-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS
+User-Agent: curl/%VERSION
Accept: */*
GET /1530002 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="testrealm", nonce="1053604145", uri="/1530002", response="f84511b014fdd0ba6494f42871079c32"
-User-Agent: curl/7.11.0-CVS (i686-pc-linux-gnu) libcurl/7.11.0-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS
+User-Agent: curl/%VERSION
Accept: */*
GET /1530002 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="testrealm", nonce="999999", uri="/1530002", cnonce="MTA4MzIy", nc="00000001", qop="auth", response="25291c357671604a16c0242f56721c07", algorithm=MD5
-User-Agent: curl/7.11.0-CVS (i686-pc-linux-gnu) libcurl/7.11.0-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1538 b/tests/data/test1538
index ea8eddbb8..03481d56e 100644
--- a/tests/data/test1538
+++ b/tests/data/test1538
@@ -129,7 +129,8 @@ e93: API function called from within callback
e94: An authentication function returned an error
e95: HTTP/3 error
e96: QUIC connection error
-e97: Unknown error
+e97: proxy handshake error
+e98: Unknown error
m-1: Please call curl_multi_perform() soon
m0: No error
m1: Invalid multi handle
diff --git a/tests/data/test154 b/tests/data/test154
index 3d693f4b3..616051cbc 100644
--- a/tests/data/test154
+++ b/tests/data/test154
@@ -82,12 +82,10 @@ four is the number of lines
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /154 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 85
Expect: 100-continue
@@ -95,7 +93,7 @@ Expect: 100-continue
PUT /154 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="gimme all yer s3cr3ts", nonce="11223344", uri="/154", response="b71551e12d1c456e47d8388ecb2edeca"
-User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 85
Expect: 100-continue
diff --git a/tests/data/test155 b/tests/data/test155
index 0cfd10eea..6e19a4f26 100644
--- a/tests/data/test155
+++ b/tests/data/test155
@@ -108,12 +108,10 @@ four is the number of lines
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /155 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 85
Expect: 100-continue
@@ -121,13 +119,14 @@ Expect: 100-continue
PUT /155 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 0
PUT /155 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAADj3hs3u3j0kgJqCrLM+74BmaoNHDfIJjHRlc3R1c2VyY3VybGhvc3Q=
-User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 85
Expect: 100-continue
diff --git a/tests/data/test1551 b/tests/data/test1551
index 507266a85..c41a14643 100644
--- a/tests/data/test1551
+++ b/tests/data/test1551
@@ -47,9 +47,6 @@ http://%HOSTIP:%HTTPPORT/1551
</client>
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1551 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test1556 b/tests/data/test1556
index 0f99abd81..f64e76e99 100644
--- a/tests/data/test1556
+++ b/tests/data/test1556
@@ -20,7 +20,7 @@ Content-Length: 6
Connection: close
Content-Type: text/html
Funny-head: yesyes
-Long: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+Long: %repeat[100001 x A]%
-foo-
</data>
@@ -46,9 +46,6 @@ http://%HOSTIP:%HTTPPORT/1556
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1556 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test156 b/tests/data/test156
index 098de218d..fafedc299 100644
--- a/tests/data/test156
+++ b/tests/data/test156
@@ -40,13 +40,10 @@ four is the number of lines
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /156 HTTP/1.1
-User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 85
Expect: 100-continue
diff --git a/tests/data/test1561 b/tests/data/test1561
index 69352fda2..86459b25f 100644
--- a/tests/data/test1561
+++ b/tests/data/test1561
@@ -73,24 +73,21 @@ Cookies set over HTTP can't override secure ones
</command>
</client>
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /15610001 HTTP/1.1
Host: www.example.com
-User-Agent: curl/7.62.0-DEV
+User-Agent: curl/%VERSION
Accept: */*
GET /15610002 HTTP/1.1
Host: www.example.com
-User-Agent: curl/7.62.0-DEV
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
<file name="log/jar1561.txt" mode="text">
# Netscape HTTP Cookie File
-# https://curl.haxx.se/docs/http-cookies.html
+# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
.example.com TRUE /foo FALSE 0 public yes
diff --git a/tests/data/test1562 b/tests/data/test1562
index 59cb9ccba..af29f54bc 100644
--- a/tests/data/test1562
+++ b/tests/data/test1562
@@ -48,21 +48,21 @@ Expire secure cookies over HTTPS
</command>
</client>
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /15620001 HTTP/1.1
Host: www.example.com
+User-Agent: curl/%VERSION
Accept: */*
GET /15620002 HTTP/1.1
Host: www.example.com
+User-Agent: curl/%VERSION
Accept: */*
Cookie: foo=123
GET /15620001 HTTP/1.1
Host: www.example.com
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1563 b/tests/data/test1563
index a3597b9b5..7d88ddc68 100644
--- a/tests/data/test1563
+++ b/tests/data/test1563
@@ -33,15 +33,13 @@ http://%HOSTIP:%HTTPPORT/15630001 -L -H "Host: www.example.com"
</command>
</client>
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<errorcode>
1
</errorcode>
<protocol>
GET /15630001 HTTP/1.1
Host: www.example.com
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1566 b/tests/data/test1566
index e6f81711d..90cb40a5e 100644
--- a/tests/data/test1566
+++ b/tests/data/test1566
@@ -35,7 +35,7 @@ http
http://%HOSTIP:%HTTPPORT/1566 -o log/output1566 --etag-compare log/etag1566
</command>
<file name="log/etag1566">
-123456
+"123456"
</file>
<file1 name="log/output1566">
downloaded already
@@ -46,12 +46,10 @@ downloaded already
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1566 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
If-None-Match: "123456"
diff --git a/tests/data/test1567 b/tests/data/test1567
index 088ebf497..ff779df08 100644
--- a/tests/data/test1567
+++ b/tests/data/test1567
@@ -48,9 +48,6 @@ http://%HOSTIP:%HTTPPORT/1567
</client>
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1567 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test157 b/tests/data/test157
index 77700f6ad..fee7a6a44 100644
--- a/tests/data/test157
+++ b/tests/data/test157
@@ -34,12 +34,10 @@ http://%HOSTIP:%HTTPPORT/157 -u testuser:testpass --anyauth
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /157 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test158 b/tests/data/test158
index dca51b163..238399a05 100644
--- a/tests/data/test158
+++ b/tests/data/test158
@@ -31,14 +31,13 @@ http://%HOSTIP:%HTTPPORT/158 -F name=daniel
# Verify data after the test has been "shot"
<verify>
<strip>
-^User-Agent:.*
^Content-Type: multipart/form-data.*
^-----------------------.*
</strip>
<protocol>
POST /158 HTTP/1.1
-User-Agent: curl/7.11.2-CVS (i686-pc-linux-gnu) libcurl/7.11.2-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 145
Content-Type: multipart/form-data; boundary=----------------------------4f12fcdaa3bc
diff --git a/tests/data/test159 b/tests/data/test159
index a56986fba..bb94583bd 100644
--- a/tests/data/test159
+++ b/tests/data/test159
@@ -69,14 +69,11 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /159 HTTP/1.0
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1591 b/tests/data/test1591
index 526933a0e..ce0c2687a 100644
--- a/tests/data/test1591
+++ b/tests/data/test1591
@@ -40,9 +40,6 @@ more than one byte
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /bzz/1591 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test1593 b/tests/data/test1593
index 405aa84e5..6719a3261 100644
--- a/tests/data/test1593
+++ b/tests/data/test1593
@@ -35,9 +35,6 @@ http://%HOSTIP:%HTTPPORT/1593
</client>
<verify>
-<strip>
-^User-Agent:.*
-</strip>
# Note here the lack of If-Modified-Since
<protocol>
GET /1593 HTTP/1.1
diff --git a/tests/data/test1594 b/tests/data/test1594
index 4907ca2be..f29fdd687 100644
--- a/tests/data/test1594
+++ b/tests/data/test1594
@@ -36,9 +36,6 @@ http://%HOSTIP:%HTTPPORT/1594
</client>
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1594 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test1595 b/tests/data/test1595
index 29b2b865f..0216788e0 100644
--- a/tests/data/test1595
+++ b/tests/data/test1595
@@ -35,9 +35,6 @@ http://%HOSTIP:%HTTPPORT/1595
</client>
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1595 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test1596 b/tests/data/test1596
index 77a10f08a..62ceab4b8 100644
--- a/tests/data/test1596
+++ b/tests/data/test1596
@@ -36,9 +36,6 @@ http://%HOSTIP:%HTTPPORT/1596
</client>
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1596 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test16 b/tests/data/test16
index 399aa9420..f8510adcf 100644
--- a/tests/data/test16
+++ b/tests/data/test16
@@ -40,13 +40,11 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://we.want.that.site.com/16 HTTP/1.1
Host: we.want.that.site.com
Proxy-Authorization: Basic ZmFrZUB1c2VyOmxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZw==
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test160 b/tests/data/test160
index df80aef97..4b1c5eddc 100644
--- a/tests/data/test160
+++ b/tests/data/test160
@@ -56,16 +56,15 @@ Connection: close
surprise2
</stdout>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/160 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /wantmore/1600001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test162 b/tests/data/test162
index 29791d9af..d15474585 100644
--- a/tests/data/test162
+++ b/tests/data/test162
@@ -44,14 +44,11 @@ http://%HOSTIP:%HTTPPORT/162 --proxy http://%HOSTIP:%HTTPPORT --proxy-user foo:b
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
GET http://%HOSTIP:%HTTPPORT/162 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.8.1-pre3 (sparc-sun-solaris2.7) libcurl 7.8.1-pre3 (OpenSSL 0.9.6a) (krb4 enabled)
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test163 b/tests/data/test163
index b4e2d260f..e4f720612 100644
--- a/tests/data/test163
+++ b/tests/data/test163
@@ -46,12 +46,12 @@ yes please
# Verify data after the test has been "shot"
<verify>
<strip>
-^(User-Agent:|Content-Type: multipart/form-data;|------------).*
+^(Content-Type: multipart/form-data;|------------).*
</strip>
<protocol>
POST /we/want/163 HTTP/1.1
-User-Agent: curl/7.11.2-CVS (i686-pc-linux-gnu) libcurl/7.11.2-CVS OpenSSL/0.9.6b zlib/1.1.4 c-ares/1.0.0
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 304
Content-Type: multipart/form-data; boundary=----------------------------c2d1767eb6ac
diff --git a/tests/data/test1630 b/tests/data/test1630
index 1d381c7b0..7bf406636 100644
--- a/tests/data/test1630
+++ b/tests/data/test1630
@@ -41,13 +41,11 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<proxy>
GET http://we.want.that.site.com/1630 HTTP/1.1
Host: we.want.that.site.com
Proxy-Authorization: Basic ZmFrZUB1c2VyOmxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZw==
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1631 b/tests/data/test1631
index cd36b1d9b..be4a24a31 100644
--- a/tests/data/test1631
+++ b/tests/data/test1631
@@ -46,6 +46,7 @@ FTP through HTTPS-proxy
-p -x https://%HOSTIP:%HTTPSPROXYPORT ftp://ftp.site.thru.https.proxy:%FTPPORT/1631 --proxy-insecure
</command>
<features>
+http
proxy
</features>
</client>
@@ -74,8 +75,6 @@ Proxy-Connection: Keep-Alive
<protocol>
USER anonymous
PASS ftp@example.com
-PBSZ 0
-PROT P
PWD
EPSV
TYPE I
diff --git a/tests/data/test1632 b/tests/data/test1632
index b10b2a68a..296137bff 100644
--- a/tests/data/test1632
+++ b/tests/data/test1632
@@ -55,6 +55,7 @@ FTP through HTTPS-proxy, with connection re-use
-p -x https://%HOSTIP:%HTTPSPROXYPORT ftp://ftp.site.thru.https.proxy:%FTPPORT/1632 --proxy-insecure ftp://ftp.site.thru.https.proxy:%FTPPORT/16320002
</command>
<features>
+http
proxy
</features>
</client>
@@ -89,8 +90,6 @@ Proxy-Connection: Keep-Alive
<protocol>
USER anonymous
PASS ftp@example.com
-PBSZ 0
-PROT P
PWD
EPSV
TYPE I
diff --git a/tests/data/test1633 b/tests/data/test1633
index 5d29ef139..6b6e1eb9f 100644
--- a/tests/data/test1633
+++ b/tests/data/test1633
@@ -68,28 +68,29 @@ http://%HOSTIP:%HTTPPORT/1633 -d moo --retry 1 -L
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
POST /1633 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 3
Content-Type: application/x-www-form-urlencoded
mooGET /16330002 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
POST /1633 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 3
Content-Type: application/x-www-form-urlencoded
mooGET /16330002 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test164 b/tests/data/test164
index 9240611dd..97e2c5eac 100644
--- a/tests/data/test164
+++ b/tests/data/test164
@@ -54,13 +54,11 @@ http://%HOSTIP:%HTTPPORT/want/164 -r 0-10,12-15
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/164 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Range: bytes=0-10,12-15
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test165 b/tests/data/test165
index 47de3919b..355394272 100644
--- a/tests/data/test165
+++ b/tests/data/test165
@@ -49,17 +49,16 @@ http://www.åäö.se/page/165 -x %HOSTIP:%HTTPPORT http://www.große.de/page/165
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://www.xn--4cab6c.se/page/165 HTTP/1.1
Host: www.xn--4cab6c.se
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://www.xn--groe-xna.de/page/165 HTTP/1.1
Host: www.xn--groe-xna.de
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test1653 b/tests/data/test1653
index 59ec3f396..fff7f6e56 100644
--- a/tests/data/test1653
+++ b/tests/data/test1653
@@ -14,7 +14,7 @@ none
unittest
</features>
<name>
-urlapi
+urlapi port number parsing
</name>
</client>
</testcase>
diff --git a/tests/data/test1654 b/tests/data/test1654
index 6155635ab..f8f90f949 100644
--- a/tests/data/test1654
+++ b/tests/data/test1654
@@ -39,7 +39,7 @@ rubbish
</client>
<verify>
<file name="log/1654-out" mode="text">
-# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html
+# Your alt-svc cache. https://curl.se/docs/alt-svc.html
# This file was generated by libcurl! Edit at your own risk.
h2 example.com 443 h3 shiny.example.com 8443 "20191231 00:00:00" 0 1
h2 foo.example.com 443 h3 shiny.example.com 8443 "20291231 23:30:00" 0 1
diff --git a/tests/data/test166 b/tests/data/test166
index f170752e6..697a2452a 100644
--- a/tests/data/test166
+++ b/tests/data/test166
@@ -38,12 +38,12 @@ data inside the file
# Verify data after the test has been "shot"
<verify>
<strip>
-^(User-Agent:|Content-Type: multipart/form-data;|------------).*
+^(Content-Type: multipart/form-data;|------------).*
</strip>
<protocol>
POST /we/want/166 HTTP/1.1
-User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b zlib/1.1.4 c-ares/1.2.0 libidn/0.4.3
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 223
Content-Type: multipart/form-data; boundary=----------------------------b0b3d6d23991
diff --git a/tests/data/test1660 b/tests/data/test1660
new file mode 100644
index 000000000..0e081d7c0
--- /dev/null
+++ b/tests/data/test1660
@@ -0,0 +1,81 @@
+<testcase>
+<info>
+<keywords>
+unittest
+HSTS
+</keywords>
+</info>
+
+<client>
+<server>
+none
+</server>
+<features>
+unittest
+HSTS
+</features>
+
+<file name="log/input1660">
+# Your HSTS cache. https://curl.se/docs/hsts.html
+# This file was generated by libcurl! Edit at your own risk.
+.readfrom.example "20211001 04:47:41"
+.old.example "20161001 04:47:41"
+</file>
+
+# This date is exactly "20190124 22:34:21" UTC
+<setenv>
+CURL_TIME=1548369261
+</setenv>
+<name>
+HSTS
+</name>
+<command>
+-
+</command>
+</client>
+
+<verify>
+<stdout>
+readfrom.example [readfrom.example]: 1633063661 includeSubDomains
+'old.example' is not HSTS
+'readfrom.example' is not HSTS
+example.com [example.com]: 1579905261
+example.com [example.com]: 1569905261
+example.com [example.com]: 1569905261
+example.com [example.com]: 1569905261 includeSubDomains
+example.org [example.org]: 1579905261
+Input 8: error 43
+Input 9: error 43
+this.example [this.example]: 1548400797
+'this.example' is not HSTS
+Input 12: error 43
+Input 13: error 43
+Input 14: error 43
+3.example.com [example.com]: 1569905261 includeSubDomains
+3.example.com [example.com]: 1569905261 includeSubDomains
+foo.example.com [example.com]: 1569905261 includeSubDomains
+'foo.xample.com' is not HSTS
+'forexample.net' is not HSTS
+'forexample.net' is not HSTS
+'example.net' is not HSTS
+expire.example [expire.example]: 1548369268
+Number of entries: 3
+expire.example [expire.example]: 1548369268
+expire.example [expire.example]: 1548369268
+expire.example [expire.example]: 1548369268
+expire.example [expire.example]: 1548369268
+expire.example [expire.example]: 1548369268
+expire.example [expire.example]: 1548369268
+expire.example [expire.example]: 1548369268
+'expire.example' is not HSTS
+'expire.example' is not HSTS
+'expire.example' is not HSTS
+</stdout>
+<file name="log/hsts1660">
+# Your HSTS cache. https://curl.se/docs/hsts.html
+# This file was generated by libcurl! Edit at your own risk.
+.example.com "20191001 04:47:41"
+example.org "20200124 22:34:21"
+</file>
+</verify>
+</testcase>
diff --git a/tests/data/test167 b/tests/data/test167
index e08555ecc..5067e779a 100644
--- a/tests/data/test167
+++ b/tests/data/test167
@@ -57,14 +57,11 @@ http://data.from.server.requiring.digest.hohoho.com/167 --proxy http://%HOSTIP:%
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
GET http://data.from.server.requiring.digest.hohoho.com/167 HTTP/1.1
Host: data.from.server.requiring.digest.hohoho.com
Proxy-Authorization: Basic Zm9vOmJhcg==
-User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b zlib/1.1.4 c-ares/1.2.0 libidn/0.4.3
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
@@ -72,7 +69,7 @@ GET http://data.from.server.requiring.digest.hohoho.com/167 HTTP/1.1
Host: data.from.server.requiring.digest.hohoho.com
Proxy-Authorization: Basic Zm9vOmJhcg==
Authorization: Digest username="digest", realm="weirdorealm", nonce="12345", uri="/167", response="13c7c02a252cbe1c46d8669898a3be26"
-User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b zlib/1.1.4 c-ares/1.2.0 libidn/0.4.3
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test168 b/tests/data/test168
index fb8762044..ddad8bb77 100644
--- a/tests/data/test168
+++ b/tests/data/test168
@@ -71,20 +71,17 @@ http://data.from.server.requiring.digest.hohoho.com/168 --proxy http://%HOSTIP:%
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
GET http://data.from.server.requiring.digest.hohoho.com/168 HTTP/1.1
Host: data.from.server.requiring.digest.hohoho.com
-User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b zlib/1.1.4 c-ares/1.2.0 libidn/0.4.3
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://data.from.server.requiring.digest.hohoho.com/168 HTTP/1.1
Host: data.from.server.requiring.digest.hohoho.com
Proxy-Authorization: Digest username="foo", realm="weirdorealm", nonce="12345", uri="/168", response="fb8608e00ad9239a3dedb14bc8575976"
-User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b zlib/1.1.4 c-ares/1.2.0 libidn/0.4.3
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
@@ -92,7 +89,7 @@ GET http://data.from.server.requiring.digest.hohoho.com/168 HTTP/1.1
Host: data.from.server.requiring.digest.hohoho.com
Proxy-Authorization: Digest username="foo", realm="weirdorealm", nonce="12345", uri="/168", response="fb8608e00ad9239a3dedb14bc8575976"
Authorization: Digest username="digest", realm="realmweirdo", nonce="123456", uri="/168", response="ca87f2d768a231e2d637a55698d5c416"
-User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.3
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test169 b/tests/data/test169
index 209dd9d90..6d30b2ade 100644
--- a/tests/data/test169
+++ b/tests/data/test169
@@ -101,28 +101,25 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
GET http://data.from.server.requiring.digest.hohoho.com/169 HTTP/1.1
Host: data.from.server.requiring.digest.hohoho.com
Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.3
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://data.from.server.requiring.digest.hohoho.com/169 HTTP/1.1
Host: data.from.server.requiring.digest.hohoho.com
Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAADj3hs3u3j0kgJqCrLM+74BmaoNHDfIJjHRlc3R1c2VyY3VybGhvc3Q=
-User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.3
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://data.from.server.requiring.digest.hohoho.com/169 HTTP/1.1
Host: data.from.server.requiring.digest.hohoho.com
Authorization: Digest username="digest", realm="r e a l m", nonce="abcdef", uri="/169", response="95d48591985a03c4b49cb962aa7bd3e6"
-User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.3
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test170 b/tests/data/test170
index 9b41ddd7f..58c2a3fe1 100644
--- a/tests/data/test170
+++ b/tests/data/test170
@@ -33,14 +33,11 @@ http://a.galaxy.far.far.away/170 --proxy http://%HOSTIP:%HTTPPORT --proxy-user f
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
POST http://a.galaxy.far.far.away/170 HTTP/1.1
Host: a.galaxy.far.far.away
Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 libidn/0.4.3
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 0
diff --git a/tests/data/test1700 b/tests/data/test1700
index 9ab46c9cd..39260bc89 100644
--- a/tests/data/test1700
+++ b/tests/data/test1700
@@ -54,17 +54,18 @@ http://%HOSTIP:%HTTP2PORT/1700 --http2 http://%HOSTIP:%HTTP2PORT/17000001
# Verify data after the test has been "shot"
<verify>
<strip>
-^User-Agent:.*
^X-Forwarded-Proto:.*
^Via:.*
</strip>
<protocol>
GET /1700 HTTP/1.1
Host: %HOSTIP:%HTTP2PORT
+User-Agent: curl/%VERSION
Accept: */*
GET /17000001 HTTP/1.1
Host: %HOSTIP:%HTTP2PORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
@@ -81,7 +82,6 @@ accept-ranges: bytes
content-length: 6
content-type: text/html
funny-head: yesyes
-server: cut-out
via: 1.1 nghttpx
-foo-
@@ -89,13 +89,12 @@ HTTP/2 200
date: Thu, 09 Nov 2010 14:49:00 GMT
content-length: 6
content-type: text/html
-server: cut-out
via: 1.1 nghttpx
-maa-
</stdout>
<stripfile>
-s/^server:.*/server: cut-out /
+s/^server: nghttpx.*\r?\n//
</stripfile>
</verify>
</testcase>
diff --git a/tests/data/test1701 b/tests/data/test1701
index 494328877..26da95f34 100644
--- a/tests/data/test1701
+++ b/tests/data/test1701
@@ -45,13 +45,13 @@ http://%HOSTIP:%HTTP2PORT/1701 --http2 -d "datatosend"
# Verify data after the test has been "shot"
<verify>
<strip>
-^User-Agent:.*
^X-Forwarded-Proto:.*
^Via:.*
</strip>
<protocol nonewline="yes">
POST /1701 HTTP/1.1
Host: %HOSTIP:%HTTP2PORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 10
Content-Type: application/x-www-form-urlencoded
@@ -71,13 +71,12 @@ accept-ranges: bytes
content-length: 6
content-type: text/html
funny-head: yesyes
-server: cut-out
via: 1.1 nghttpx
-foo-
</stdout>
<stripfile>
-s/^server:.*/server: cut-out /
+s/^server: nghttpx.*\r?\n//
</stripfile>
</verify>
</testcase>
diff --git a/tests/data/test1702 b/tests/data/test1702
index 903a737c9..bbb9084e2 100644
--- a/tests/data/test1702
+++ b/tests/data/test1702
@@ -44,13 +44,13 @@ http://%HOSTIP:%HTTP2PORT/1702 --http2 --head
# Verify data after the test has been "shot"
<verify>
<strip>
-^User-Agent:.*
^X-Forwarded-Proto:.*
^Via:.*
</strip>
<protocol>
HEAD /1702 HTTP/1.1
Host: %HOSTIP:%HTTP2PORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
@@ -67,12 +67,11 @@ accept-ranges: bytes
content-length: 6
content-type: text/html
funny-head: yesyes
-server: cut-out
via: 1.1 nghttpx
</stdout>
<stripfile>
-s/^server:.*/server: cut-out /
+s/^server: nghttpx.*\r?\n//
</stripfile>
</verify>
</testcase>
diff --git a/tests/data/test171 b/tests/data/test171
index 482c0b7e2..e79e8e03d 100644
--- a/tests/data/test171
+++ b/tests/data/test171
@@ -40,19 +40,17 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://z.x.com/171 HTTP/1.1
Host: z.x.com
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
</protocol>
<file name="log/jar171" mode="text">
# Netscape HTTP Cookie File
-# https://curl.haxx.se/docs/http-cookies.html
+# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
.z.x.com TRUE / FALSE 0 XToken xt
diff --git a/tests/data/test172 b/tests/data/test172
index ad3628429..ca6d3cd73 100644
--- a/tests/data/test172
+++ b/tests/data/test172
@@ -31,7 +31,7 @@ http://%HOSTIP:%HTTPPORT/we/want/172 -b log/jar172.txt -b "tool=curl; name=fool"
</command>
<file name="log/jar172.txt">
# Netscape HTTP Cookie File
-# https://curl.haxx.se/docs/http-cookies.html
+# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
.%HOSTIP TRUE /silly/ FALSE 0 ismatch this
@@ -42,12 +42,10 @@ http://%HOSTIP:%HTTPPORT/we/want/172 -b log/jar172.txt -b "tool=curl; name=fool"
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/172 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Cookie: nodomain=value; partmatch=present; tool=curl; name=fool
diff --git a/tests/data/test173 b/tests/data/test173
index 865ef7ba2..1484cbe03 100644
--- a/tests/data/test173
+++ b/tests/data/test173
@@ -46,12 +46,12 @@ line8
# Verify data after the test has been "shot"
<verify>
<strip>
-^(User-Agent:|Content-Type: multipart/form-data;|------------).*
+^(Content-Type: multipart/form-data;|------------).*
</strip>
<protocol>
POST /we/want/173 HTTP/1.1
-User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 360
Content-Type: multipart/form-data; boundary=----------------------------5dbea401cd8c
diff --git a/tests/data/test174 b/tests/data/test174
index 9767f2f52..e5a9d6fcb 100644
--- a/tests/data/test174
+++ b/tests/data/test174
@@ -35,13 +35,10 @@ http://%HOSTIP:%HTTPPORT/174 -u testuser:testpass --anyauth -d "junkelijunk"
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /174 HTTP/1.1
-User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 11
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test175 b/tests/data/test175
index 9e005f1f5..8b49a32b5 100644
--- a/tests/data/test175
+++ b/tests/data/test175
@@ -62,20 +62,17 @@ http://%HOSTIP:%HTTPPORT/175 -u auser:apasswd --digest -d "junkelijunk"
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /175 HTTP/1.1
-User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
POST /175 HTTP/1.1
-User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 11
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test176 b/tests/data/test176
index e18837af1..5fe310fac 100644
--- a/tests/data/test176
+++ b/tests/data/test176
@@ -64,21 +64,18 @@ http://%HOSTIP:%HTTPPORT/176 -u auser:apasswd --ntlm -d "junkelijunk"
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /176 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
POST /176 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
-User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 11
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test177 b/tests/data/test177
index 495dea9b4..e31f1b7fa 100644
--- a/tests/data/test177
+++ b/tests/data/test177
@@ -38,13 +38,10 @@ http://%HOSTIP:%HTTPPORT/177 -u auser:apasswd --digest -d "junkelijunk"
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
POST /177 HTTP/1.1
-User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test178 b/tests/data/test178
index d22d8149f..b67e353ac 100644
--- a/tests/data/test178
+++ b/tests/data/test178
@@ -41,12 +41,10 @@ http://%HOSTIP:%HTTPPORT/178
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /178 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test179 b/tests/data/test179
index 3a94c00ba..9f7bdedcf 100644
--- a/tests/data/test179
+++ b/tests/data/test179
@@ -45,12 +45,10 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://supertrooper.fake/c/179 HTTP/1.1
Host: supertrooper.fake
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Cookie: moo2=indeed
diff --git a/tests/data/test18 b/tests/data/test18
index e1d76398c..0fe92f79b 100644
--- a/tests/data/test18
+++ b/tests/data/test18
@@ -47,23 +47,20 @@ multiple requests using {} in URL
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /18 HTTP/1.1
-User-Agent: curl/7.8.1-pre3 (sparc-sun-solaris2.7) libcurl 7.8.1-pre3 (OpenSSL 0.9.6a) (krb4 enabled)
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /180002 HTTP/1.1
-User-Agent: curl/7.8.1-pre3 (sparc-sun-solaris2.7) libcurl 7.8.1-pre3 (OpenSSL 0.9.6a) (krb4 enabled)
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /180003 HTTP/1.1
-User-Agent: curl/7.8.1-pre3 (sparc-sun-solaris2.7) libcurl 7.8.1-pre3 (OpenSSL 0.9.6a) (krb4 enabled)
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test180 b/tests/data/test180
index 0b2ca0373..1074e267c 100644
--- a/tests/data/test180
+++ b/tests/data/test180
@@ -44,12 +44,10 @@ the
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /we/want/180 HTTP/1.0
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 78
diff --git a/tests/data/test1800 b/tests/data/test1800
index c308c99b0..89f4292b3 100644
--- a/tests/data/test1800
+++ b/tests/data/test1800
@@ -39,12 +39,10 @@ http://%HOSTIP:%HTTPPORT/1800 --http2
</client>
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1800 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Connection: Upgrade, HTTP2-Settings
Upgrade: %H2CVER
diff --git a/tests/data/test1801 b/tests/data/test1801
index b827ab51e..15367d221 100644
--- a/tests/data/test1801
+++ b/tests/data/test1801
@@ -49,12 +49,10 @@ http://%HOSTIP:%HTTPPORT/1801 --http2
</client>
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1801 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Connection: Upgrade, HTTP2-Settings
Upgrade: %H2CVER
diff --git a/tests/data/test181 b/tests/data/test181
index b6b55cb99..c2f813579 100644
--- a/tests/data/test181
+++ b/tests/data/test181
@@ -44,12 +44,10 @@ the
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
POST /we/want/181 HTTP/1.0
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 79
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test183 b/tests/data/test183
index cf992a26f..d72081c47 100644
--- a/tests/data/test183
+++ b/tests/data/test183
@@ -37,19 +37,16 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
GET http://deathstar.another.galaxy/183 HTTP/1.1
-User-Agent: curl/7.12.2-CVS (i686-pc-linux-gnu) libcurl/7.12.2-CVS OpenSSL/0.9.6b zlib/1.1.4 libidn/0.4.6
Host: deathstar.another.galaxy
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://a.galaxy.far.far.away/183 HTTP/1.1
-User-Agent: curl/7.12.2-CVS (i686-pc-linux-gnu) libcurl/7.12.2-CVS OpenSSL/0.9.6b zlib/1.1.4 libidn/0.4.6
Host: a.galaxy.far.far.away
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test184 b/tests/data/test184
index 42e652e3b..1afb10df8 100644
--- a/tests/data/test184
+++ b/tests/data/test184
@@ -57,18 +57,16 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
GET http://deathstar.another.galaxy/184 HTTP/1.1
Host: another.visitor.stay.a.while.stay.foreeeeeever
-User-Agent: curl/7.12.2-CVS (i686-pc-linux-gnu) libcurl/7.12.2-CVS OpenSSL/0.9.6b zlib/1.1.4 libidn/0.4.6
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://yet.another.host/184 HTTP/1.1
Host: yet.another.host
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test185 b/tests/data/test185
index 3bc58a041..ba48fd87b 100644
--- a/tests/data/test185
+++ b/tests/data/test185
@@ -57,18 +57,16 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
GET http://deathstar.another.galaxy/185 HTTP/1.1
Host: another.visitor.stay.a.while.stay.foreeeeeever
-User-Agent: curl/7.12.2-CVS (i686-pc-linux-gnu) libcurl/7.12.2-CVS OpenSSL/0.9.6b zlib/1.1.4 libidn/0.4.6
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://deathstar.another.galaxy/go/west/185 HTTP/1.1
Host: another.visitor.stay.a.while.stay.foreeeeeever
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test186 b/tests/data/test186
index 4abc74a2b..f5a75c6fd 100644
--- a/tests/data/test186
+++ b/tests/data/test186
@@ -36,12 +36,12 @@ http://%HOSTIP:%HTTPPORT/we/want/186 -F "name=daniel;type=moo/foo" -F "html= <bo
# Verify data after the test has been "shot"
<verify>
<strip>
-^(User-Agent:|Content-Type: multipart/form-data;|------------).*
+^(Content-Type: multipart/form-data;|------------).*
</strip>
<protocol>
POST /we/want/186 HTTP/1.1
-User-Agent: curl/7.12.2-CVS (i686-pc-linux-gnu) libcurl/7.12.2-CVS OpenSSL/0.9.7d zlib/1.2.1.1 c-ares/1.2.0 libidn/0.5.2
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 320
Content-Type: multipart/form-data; boundary=----------------------------212d9006ceb5
diff --git a/tests/data/test187 b/tests/data/test187
index b82a6c60e..a18654122 100644
--- a/tests/data/test187
+++ b/tests/data/test187
@@ -60,16 +60,15 @@ http://%HOSTIP:%HTTPPORT?oh=what-weird=test/187 -L
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /?oh=what-weird=test/187 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /root/1870002.txt?coolsite=yes HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test188 b/tests/data/test188
index d8ca1cd47..14e95c8e8 100644
--- a/tests/data/test188
+++ b/tests/data/test188
@@ -57,20 +57,17 @@ http://%HOSTIP:%HTTPPORT/188 -C 50 -L
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /188 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Range: bytes=50-
-User-Agent: curl/7.6 (sparc-sun-solaris2.7) libcurl 7.6-pre4 (SSL 0.9.6) (krb4 enabled)
+User-Agent: curl/%VERSION
Accept: */*
GET /188 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Range: bytes=50-
-User-Agent: curl/7.12.2-CVS (i686-pc-linux-gnu) libcurl/7.12.2-CVS OpenSSL/0.9.7d zlib/1.2.1.2 libidn/0.5.2
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test189 b/tests/data/test189
index 65780f804..3435a52be 100644
--- a/tests/data/test189
+++ b/tests/data/test189
@@ -51,20 +51,17 @@ http://%HOSTIP:%HTTPPORT/189 -C 50 -L
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /189 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Range: bytes=50-
-User-Agent: curl/7.6 (sparc-sun-solaris2.7) libcurl 7.6-pre4 (SSL 0.9.6) (krb4 enabled)
+User-Agent: curl/%VERSION
Accept: */*
GET /189 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Range: bytes=50-
-User-Agent: curl/7.12.2-CVS (i686-pc-linux-gnu) libcurl/7.12.2-CVS OpenSSL/0.9.7d zlib/1.2.1.2 libidn/0.5.2
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1900 b/tests/data/test1900
deleted file mode 100644
index 2e3c93a0d..000000000
--- a/tests/data/test1900
+++ /dev/null
@@ -1,61 +0,0 @@
-<testcase>
-<info>
-<keywords>
-HTTP
-pipelining
-multi
-</keywords>
-</info>
-
-# Server-side
-<reply>
-<data>
-Adding handle 0
-Handle 0 Completed with status 0
-Adding handle 1
-Adding handle 2
-Adding handle 3
-Adding handle 4
-Adding handle 5
-Adding handle 6
-Handle 4 Completed with status 0
-Handle 5 Completed with status 0
-Handle 6 Completed with status 0
-Handle 1 Completed with status 0
-Handle 2 Completed with status 0
-Handle 3 Completed with status 0
-</data>
-</reply>
-
-# Client-side
-<client>
-<server>
-http-pipe
-</server>
-<features>
-http
-</features>
-<tool>
-lib1900
-</tool>
- <name>
-HTTP GET using pipelining
- </name>
- <command>
-http://%HOSTIP:%HTTPPIPEPORT/ log/urls1900.txt
-</command>
-<file name="log/urls1900.txt">
-0 1k.txt
-1000 100k.txt
-0 1k.txt
-0 1k.txt
-0 1k.txt
-0 1k.txt
-0 1k.txt
-</file>
-</client>
-
-# Verify data after the test has been "shot"
-<verify>
-</verify>
-</testcase>
diff --git a/tests/data/test1901 b/tests/data/test1901
deleted file mode 100644
index 793bd667a..000000000
--- a/tests/data/test1901
+++ /dev/null
@@ -1,63 +0,0 @@
-<testcase>
-<info>
-<keywords>
-HTTP
-pipelining
-multi
-flaky
-</keywords>
-</info>
-
-# Server-side
-<reply>
-<data>
-Adding handle 0
-Handle 0 Completed with status 0
-Adding handle 1
-Adding handle 2
-Adding handle 3
-Adding handle 4
-Adding handle 5
-Adding handle 6
-Handle 2 Completed with status 0
-Handle 3 Completed with status 0
-Handle 4 Completed with status 0
-Handle 1 Completed with status 0
-Handle 5 Completed with status 0
-Handle 6 Completed with status 0
-</data>
-</reply>
-
-# Client-side
-<client>
-<server>
-http-pipe
-</server>
-<features>
-http
-</features>
-<tool>
-lib1900
-</tool>
- <name>
-HTTP GET using pipelining, blocklisted site
- </name>
- <command>
-http://%HOSTIP:%HTTPPIPEPORT/ log/urls1901.txt
-</command>
-<file name="log/urls1901.txt">
-blocklist_site 127.0.0.1:%HTTPPIPEPORT
-0 1k.txt
-1000 100k.txt
-0 1k.txt
-0 1k.txt
-0 1k.txt
-0 1k.txt
-0 1k.txt
-</file>
-</client>
-
-# Verify data after the test has been "shot"
-<verify>
-</verify>
-</testcase>
diff --git a/tests/data/test1902 b/tests/data/test1902
deleted file mode 100644
index 3c999316b..000000000
--- a/tests/data/test1902
+++ /dev/null
@@ -1,62 +0,0 @@
-<testcase>
-<info>
-<keywords>
-HTTP
-pipelining
-multi
-flaky
-</keywords>
-</info>
-
-# Server-side
-<reply>
-<data>
-Adding handle 0
-Handle 0 Completed with status 0
-Adding handle 1
-Adding handle 2
-Adding handle 3
-Adding handle 4
-Adding handle 5
-Adding handle 6
-Handle 1 Completed with status 0
-Handle 4 Completed with status 0
-Handle 5 Completed with status 0
-Handle 6 Completed with status 0
-Handle 2 Completed with status 0
-Handle 3 Completed with status 0
-</data>
-</reply>
-
-# Client-side
-<client>
-<server>
-http-pipe
-</server>
-<features>
-http
-</features>
-<tool>
-lib1900
-</tool>
- <name>
-HTTP GET using pipelining, broken pipe
- </name>
- <command>
-http://%HOSTIP:%HTTPPIPEPORT/ log/urls1902.txt
-</command>
-<file name="log/urls1902.txt">
-0 1k.txt
-1000 connection_close.txt
-1 1k.txt
-2 1k.txt
-3 1k.txt
-4 1k.txt
-5 1k.txt
-</file>
-</client>
-
-# Verify data after the test has been "shot"
-<verify>
-</verify>
-</testcase>
diff --git a/tests/data/test1903 b/tests/data/test1903
deleted file mode 100644
index 219ffe11c..000000000
--- a/tests/data/test1903
+++ /dev/null
@@ -1,62 +0,0 @@
-<testcase>
-<info>
-<keywords>
-HTTP
-pipelining
-multi
-flaky
-</keywords>
-</info>
-
-# Server-side
-<reply>
-<data>
-Adding handle 0
-Handle 0 Completed with status 0
-Adding handle 1
-Adding handle 2
-Adding handle 3
-Adding handle 4
-Adding handle 5
-Adding handle 6
-Handle 2 Completed with status 0
-Handle 3 Completed with status 0
-Handle 4 Completed with status 0
-Handle 5 Completed with status 0
-Handle 6 Completed with status 0
-Handle 1 Completed with status 0
-</data>
-</reply>
-
-# Client-side
-<client>
-<server>
-http-pipe
-</server>
-<features>
-http
-</features>
-<tool>
-lib1900
-</tool>
- <name>
-HTTP GET using pipelining, penalized on content-length
- </name>
- <command>
-http://%HOSTIP:%HTTPPIPEPORT/ log/urls1903.txt
-</command>
-<file name="log/urls1903.txt">
-0 1k.txt
-1000 100k.txt
-550 alphabet.txt
-10 alphabet.txt
-10 alphabet.txt
-10 alphabet.txt
-10 alphabet.txt
-</file>
-</client>
-
-# Verify data after the test has been "shot"
-<verify>
-</verify>
-</testcase>
diff --git a/tests/data/test1904 b/tests/data/test1904
index 760285472..f75e87dab 100644
--- a/tests/data/test1904
+++ b/tests/data/test1904
@@ -61,20 +61,17 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<proxy>
CONNECT test.1904:%HTTPPORT HTTP/1.1
Host: test.1904:%HTTPPORT
-User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
</proxy>
<protocol>
GET /we/want/that/page/1904 HTTP/1.1
Host: test.1904:%HTTPPORT
-User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1905 b/tests/data/test1905
index 0459b10b4..ee3015368 100644
--- a/tests/data/test1905
+++ b/tests/data/test1905
@@ -39,9 +39,6 @@ http://%HOSTIP:%HTTPPORT/we/want/1905
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/1905 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
@@ -50,7 +47,7 @@ Accept: */*
</protocol>
<file name="log/cookies1905" mode="text">
# Netscape HTTP Cookie File
-# https://curl.haxx.se/docs/http-cookies.html
+# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
%HOSTIP FALSE /we/want/ FALSE 0 secondcookie present
diff --git a/tests/data/test1906 b/tests/data/test1906
index 0ff2b2be0..0c476a154 100644
--- a/tests/data/test1906
+++ b/tests/data/test1906
@@ -39,9 +39,6 @@ http://%HOSTIP:%HTTPPORT/1906
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1906 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test1907 b/tests/data/test1907
index 93f37051e..85cabde16 100644
--- a/tests/data/test1907
+++ b/tests/data/test1907
@@ -37,9 +37,6 @@ lib1907
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1907 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test1908 b/tests/data/test1908
index bf23ef9fc..19f8d0d1d 100644
--- a/tests/data/test1908
+++ b/tests/data/test1908
@@ -8,7 +8,7 @@ CURLINFO_EFFECTIVE_URL
# Server-side
<reply>
<data nocheck="yes">
-HTTP/1.1 200 OK
+HTTP/1.1 200 OK swsbounce
Date: Thu, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Content-Type: text/html
@@ -17,6 +17,15 @@ Content-Length: 0
alt-svc: h2="3dbbdetxoyw4nsp6c3cc456oj2ays6s43ezxzsfxxri3h5xqd.example:443"; ma=315360000; persist=1
</data>
+
+# This is the second response
+<data1 nocheck="yes">
+HTTP/1.1 200 OK
+Connection: close
+Content-Length: 0
+alt-svc: h2="second.example:443"; ma=315360000;
+
+</data1>
</reply>
# Client-side
@@ -48,14 +57,15 @@ lib1908
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1908 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Accept: */*
+GET /1908 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Accept: */*
+
</protocol>
<stripfile>
# strip out the (dynamic) expire date from the file so that the rest
@@ -63,7 +73,7 @@ Accept: */*
s/\"([^\"]*)\"/TIMESTAMP/
</stripfile>
<file name="log/altsvc-1908" mode="text">
-# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html
+# Your alt-svc cache. https://curl.se/docs/alt-svc.html
# This file was generated by libcurl! Edit at your own risk.
h1 127.0.0.1 %HTTPPORT h2 3dbbdetxoyw4nsp6c3cc456oj2ays6s43ezxzsfxxri3h5xqd.example 443 TIMESTAMP 1 0
</file>
diff --git a/tests/data/test1909 b/tests/data/test1909
index bde0e5e0f..ba082529a 100644
--- a/tests/data/test1909
+++ b/tests/data/test1909
@@ -43,16 +43,15 @@ HTTP GET --retry-all-errors to overcome partial transfer
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1909 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /1909 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test1910 b/tests/data/test1910
index a1b3f5756..cd44c0269 100644
--- a/tests/data/test1910
+++ b/tests/data/test1910
@@ -26,7 +26,7 @@ Content-Type: text/html
Content-Length: 4
hej
-</data>
+</data2>
</reply>
# Client-side
@@ -49,9 +49,6 @@ lib1910
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /1910 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test1541 b/tests/data/test1911
index e18bb47df..ec5f531af 100644
--- a/tests/data/test1541
+++ b/tests/data/test1911
@@ -1,10 +1,7 @@
<testcase>
<info>
<keywords>
-HTTP
-HTTP GET
-multi-threaded
-connection-sharing
+curl_easy_option
</keywords>
</info>
@@ -15,17 +12,15 @@ connection-sharing
# Client-side
<client>
<server>
-http
+none
</server>
+<name>
+verify that curl_easy_setopt() rejects too long string inputs
+</name>
<tool>
-lib1541
+lib1911
</tool>
- <name>
-connection sharing using 67 parallel threads for 7 seconds
- </name>
- <command>
-http://%HOSTIP:%HTTPPORT/1
-</command>
+
</client>
# Verify data after the test has been "shot"
diff --git a/tests/data/test1912 b/tests/data/test1912
new file mode 100644
index 000000000..ed6b27b5b
--- /dev/null
+++ b/tests/data/test1912
@@ -0,0 +1,30 @@
+<testcase>
+<info>
+<keywords>
+curl_easy_option
+typecheck
+</keywords>
+</info>
+
+# Server-side
+<reply>
+</reply>
+
+# Client-side
+<client>
+<server>
+none
+</server>
+<name>
+Cross validate that gcc-typecheck macros match the option types.
+</name>
+<tool>
+lib1912
+</tool>
+
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+</verify>
+</testcase>
diff --git a/tests/data/test1913 b/tests/data/test1913
new file mode 100644
index 000000000..daf749025
--- /dev/null
+++ b/tests/data/test1913
@@ -0,0 +1,41 @@
+<testcase>
+<info>
+<keywords>
+FTP
+CURLOPT_NOBODY
+</keywords>
+</info>
+
+# Server-side
+<reply>
+<servercmd>
+REPLY SIZE 550 no such file
+</servercmd>
+</reply>
+
+# Client-side
+<client>
+<server>
+ftp
+</server>
+
+# require debug so that alt-svc can work over plain old HTTP
+<name>
+FTP with NOBODY set, getting a missing file
+</name>
+<tool>
+lib1913
+</tool>
+
+<command>
+ftp://%HOSTIP:%FTPPORT/not-there/1913
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<errorcode>
+78
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/data/test1914 b/tests/data/test1914
new file mode 100644
index 000000000..1aa3e48c0
--- /dev/null
+++ b/tests/data/test1914
@@ -0,0 +1,42 @@
+<testcase>
+<info>
+<keywords>
+FTP
+CURLOPT_NOBODY
+CURLOPT_FILETIME
+</keywords>
+</info>
+
+# Server-side
+<reply>
+<servercmd>
+REPLY MDTM 550 no such file
+</servercmd>
+</reply>
+
+# Client-side
+<client>
+<server>
+ftp
+</server>
+
+# require debug so that alt-svc can work over plain old HTTP
+<name>
+FTP with NOBODY and FILETIME set, getting a missing file
+</name>
+<tool>
+lib1913
+</tool>
+
+<command>
+ftp://%HOSTIP:%FTPPORT/not-there/1913 1
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<errorcode>
+78
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/data/test1915 b/tests/data/test1915
new file mode 100644
index 000000000..850213930
--- /dev/null
+++ b/tests/data/test1915
@@ -0,0 +1,50 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HSTS
+CURLOPT_HSTSREADFUNCTION
+</keywords>
+</info>
+
+# Server-side
+<reply>
+</reply>
+
+# Client-side
+<client>
+<features>
+HSTS
+http
+</features>
+<server>
+none
+</server>
+
+# require debug so that alt-svc can work over plain old HTTP
+<name>
+HSTS read/write callbacks
+</name>
+<tool>
+lib1915
+</tool>
+
+<command>
+http://%HOSTIP:%NOLISTENPORT/not-there/1915
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+# it fails because there's nothing on that port
+<errorcode>
+7
+</errorcode>
+<stdout>
+[0/4] 1.example.com 20300320 01:02:03
+[1/4] 2.example.com 20300320 01:02:03
+[2/4] 3.example.com 20300320 01:02:03
+[3/4] 4.example.com 20300320 01:02:03
+</stdout>
+</verify>
+</testcase>
diff --git a/tests/data/test192 b/tests/data/test192
index 42cebc031..9a54a1a06 100644
--- a/tests/data/test192
+++ b/tests/data/test192
@@ -36,12 +36,10 @@ http://%HOSTIP:%HTTPPORT/192 -w "%{num_connects}\n"
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /192 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test193 b/tests/data/test193
index c5425bb3f..6a9c674e0 100644
--- a/tests/data/test193
+++ b/tests/data/test193
@@ -48,16 +48,15 @@ http://%HOSTIP:%HTTPPORT/193 -w "%{num_connects}\n" -L
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /193 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /193 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test194 b/tests/data/test194
index 730446f79..323ac0f38 100644
--- a/tests/data/test194
+++ b/tests/data/test194
@@ -55,13 +55,11 @@ http://%HOSTIP:%HTTPPORT/want/194 -C 87 --fail
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/194 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Range: bytes=87-
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test197 b/tests/data/test197
index 4d06cc5da..052a0ad34 100644
--- a/tests/data/test197
+++ b/tests/data/test197
@@ -44,16 +44,15 @@ http://%HOSTIP:%HTTPPORT/197 --retry 1000
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /197 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /197 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test198 b/tests/data/test198
index 0200366c5..56dd74b4c 100644
--- a/tests/data/test198
+++ b/tests/data/test198
@@ -53,16 +53,15 @@ http://%HOSTIP:%HTTPPORT/198 --retry 1000
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /198 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /198 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test199 b/tests/data/test199
index 72675b535..69a3cecc6 100644
--- a/tests/data/test199
+++ b/tests/data/test199
@@ -42,16 +42,15 @@ HTTP with -d, -G and {}
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /199?foo=moo&moo=poo HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /199?foo=moo&moo=poo HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2 b/tests/data/test2
index 9f9c50618..bd53ed58c 100644
--- a/tests/data/test2
+++ b/tests/data/test2
@@ -36,13 +36,11 @@ HTTP GET with user and password
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Basic ZmFrZTp1c2Vy
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2001 b/tests/data/test2001
index 9232499f9..4286f1d1e 100644
--- a/tests/data/test2001
+++ b/tests/data/test2001
@@ -63,12 +63,10 @@ moo
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /20010001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
USER anonymous
diff --git a/tests/data/test2002 b/tests/data/test2002
index efe75fa3b..cad7cdf82 100644
--- a/tests/data/test2002
+++ b/tests/data/test2002
@@ -72,12 +72,10 @@ moo
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /20020001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
USER anonymous
diff --git a/tests/data/test2003 b/tests/data/test2003
index 68ae71429..12b4722d9 100644
--- a/tests/data/test2003
+++ b/tests/data/test2003
@@ -72,12 +72,10 @@ moo
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /20030001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
USER anonymous
@@ -104,6 +102,7 @@ SIZE 20030002
RETR 20030002
GET /20030001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
QUIT
diff --git a/tests/data/test2005 b/tests/data/test2005
index f78b4be56..f26bf239a 100644
--- a/tests/data/test2005
+++ b/tests/data/test2005
@@ -64,12 +64,10 @@ perl %SRCDIR/libtest/notexists.pl log/2005 log/name2005
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2005 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2006 b/tests/data/test2006
index 4cb61192d..addf86f01 100644
--- a/tests/data/test2006
+++ b/tests/data/test2006
@@ -73,12 +73,10 @@ perl %SRCDIR/libtest/notexists.pl log/2006 log/name2006
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2006 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2007 b/tests/data/test2007
index 738ac35f9..4c456151a 100644
--- a/tests/data/test2007
+++ b/tests/data/test2007
@@ -74,12 +74,10 @@ perl %SRCDIR/libtest/notexists.pl log/2007 log/name2007
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2007 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2008 b/tests/data/test2008
index b29ba911b..ec41adb35 100644
--- a/tests/data/test2008
+++ b/tests/data/test2008
@@ -66,12 +66,10 @@ perl %SRCDIR/libtest/notexists.pl log/2008 log/name2008 log/outfile2008
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2008 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2009 b/tests/data/test2009
index 3cf4e4c48..aa71a0ac1 100644
--- a/tests/data/test2009
+++ b/tests/data/test2009
@@ -67,12 +67,10 @@ perl %SRCDIR/libtest/notexists.pl log/2009 log/name2009 log/outfile2009
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2009 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2010 b/tests/data/test2010
index 08f1bfaa4..cd0c48354 100644
--- a/tests/data/test2010
+++ b/tests/data/test2010
@@ -66,12 +66,10 @@ perl %SRCDIR/libtest/notexists.pl log/2010 log/name2010 log/outfile2010
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2010 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2011 b/tests/data/test2011
index a84502317..1d081afcb 100644
--- a/tests/data/test2011
+++ b/tests/data/test2011
@@ -64,12 +64,10 @@ perl %SRCDIR/libtest/notexists.pl log/2011 log/name2011
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2011 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2012 b/tests/data/test2012
index 6751269d5..ae627a9af 100644
--- a/tests/data/test2012
+++ b/tests/data/test2012
@@ -63,12 +63,10 @@ perl %SRCDIR/libtest/notexists.pl log/2012 log/name2012
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2012 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2023 b/tests/data/test2023
index 382b6cb8a..0b155b2d2 100644
--- a/tests/data/test2023
+++ b/tests/data/test2023
@@ -128,9 +128,6 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /20230100 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test2024 b/tests/data/test2024
index cd06b7c9f..c062b4c0f 100644
--- a/tests/data/test2024
+++ b/tests/data/test2024
@@ -142,9 +142,6 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /20240100 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test2025 b/tests/data/test2025
index 282c69850..7a8fff152 100644
--- a/tests/data/test2025
+++ b/tests/data/test2025
@@ -224,9 +224,6 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /20250100 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test2026 b/tests/data/test2026
index afbd4f31e..a505737d7 100644
--- a/tests/data/test2026
+++ b/tests/data/test2026
@@ -178,9 +178,6 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /20260100 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test2027 b/tests/data/test2027
index 3302a155d..3983e8854 100644
--- a/tests/data/test2027
+++ b/tests/data/test2027
@@ -201,9 +201,6 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /20270100 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test2028 b/tests/data/test2028
index 92a637161..c7b70c8f2 100644
--- a/tests/data/test2028
+++ b/tests/data/test2028
@@ -260,9 +260,6 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /20280100 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test2029 b/tests/data/test2029
index 59a793ebe..67313c414 100644
--- a/tests/data/test2029
+++ b/tests/data/test2029
@@ -197,9 +197,6 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /20290100 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test2030 b/tests/data/test2030
index a158a907a..1d281ab9f 100644
--- a/tests/data/test2030
+++ b/tests/data/test2030
@@ -249,9 +249,6 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /20300100 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test2031 b/tests/data/test2031
index 9acfeef72..dabba3749 100644
--- a/tests/data/test2031
+++ b/tests/data/test2031
@@ -263,9 +263,6 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /20310100 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test2032 b/tests/data/test2032
index 8200b8de5..52574fe77 100644
--- a/tests/data/test2032
+++ b/tests/data/test2032
@@ -95,9 +95,6 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /20320100 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test2033 b/tests/data/test2033
deleted file mode 100644
index 0b33ccaac..000000000
--- a/tests/data/test2033
+++ /dev/null
@@ -1,125 +0,0 @@
-<testcase>
-<info>
-<keywords>
-HTTP
-HTTP GET
-HTTP Basic auth
-HTTP NTLM auth
-pipelining
-flaky
-</keywords>
-</info>
-# Server-side
-<reply>
-
-<!-- Basic auth -->
-<data100>
-HTTP/1.1 401 Need Basic or NTLM auth
-Server: Microsoft-IIS/5.0
-Content-Type: text/html; charset=iso-8859-1
-Content-Length: 29
-WWW-Authenticate: NTLM
-WWW-Authenticate: Basic realm="testrealm"
-
-This is a bad password page!
-</data100>
-
-<!-- NTLM auth -->
-<data200>
-HTTP/1.1 401 Need Basic or NTLM auth (2)
-Server: Microsoft-IIS/5.0
-Content-Type: text/html; charset=iso-8859-1
-Content-Length: 27
-WWW-Authenticate: NTLM
-WWW-Authenticate: Basic realm="testrealm"
-
-This is not the real page!
-</data200>
-
-<data1201>
-HTTP/1.1 401 NTLM intermediate (2)
-Server: Microsoft-IIS/5.0
-Content-Type: text/html; charset=iso-8859-1
-Content-Length: 33
-WWW-Authenticate: NTLM TlRMTVNTUAACAAAACAAIADAAAACGgAEAq6U1NAWaJCIAAAAAAAAAAAAAAAA4AAAATlRMTUF1dGg=
-
-This is still not the real page!
-</data1201>
-
-<data1202>
-HTTP/1.1 200 Things are fine in server land
-Server: Microsoft-IIS/5.0
-Content-Type: text/html; charset=iso-8859-1
-Content-Length: 32
-
-Finally, this is the real page!
-</data1202>
-
-<datacheck>
-Data connection 0: 228
-Data connection 1: 228
-Data connection 2: 402
-</datacheck>
-
-</reply>
-
-# Client-side
-<client>
-<features>
-NTLM
-SSL
-!SSPI
-</features>
-<server>
-http
-</server>
-<tool>
-lib2033
-</tool>
-
- <name>
-NTLM connection mapping, pipelining enabled
- </name>
- <setenv>
-# we force our own host name, in order to make the test machine independent
-CURL_GETHOSTNAME=curlhost
-# we try to use the LD_PRELOAD hack, if not a debug build
-LD_PRELOAD=%PWD/libtest/.libs/libhostname.so
- </setenv>
- <command>
-http://%HOSTIP:%HTTPPORT/2032
-</command>
-<precheck>
-chkhostname curlhost
-</precheck>
-</client>
-
-# Verify data after the test has been "shot"
-<verify>
-<strip>
-^User-Agent:.*
-</strip>
-<protocol>
-GET /20320100 HTTP/1.1
-Host: %HOSTIP:%HTTPPORT
-Authorization: Basic dGVzdHVzZXI6dGVzdHBhc3M=
-Accept: */*
-
-GET /20320100 HTTP/1.1
-Host: %HOSTIP:%HTTPPORT
-Authorization: Basic dGVzdHVzZXI6dGVzdHBhc3M=
-Accept: */*
-
-GET /20320200 HTTP/1.1
-Host: %HOSTIP:%HTTPPORT
-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-Accept: */*
-
-GET /20320200 HTTP/1.1
-Host: %HOSTIP:%HTTPPORT
-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoABAI+/Fp9IERAQ74OsdNPbBpg7o8CVwLSO4DtFyIcZHUMKVktWIu92s2892OVpd2JzqnRlc3R1c2VyY3VybGhvc3Q=
-Accept: */*
-
-</protocol>
-</verify>
-</testcase>
diff --git a/tests/data/test2034 b/tests/data/test2034
index 9bf0a817c..57e3d8627 100644
--- a/tests/data/test2034
+++ b/tests/data/test2034
@@ -45,12 +45,10 @@ perl -e "print 'Test requires default test server host' if ( '%HOSTIP' ne '127.0
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2034 HTTP/1.1
Host: localhost:%HTTPSPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2036 b/tests/data/test2036
index 4b2ec43a8..f022d1444 100644
--- a/tests/data/test2036
+++ b/tests/data/test2036
@@ -29,9 +29,6 @@ HTTP, -O with no slash at all in the URL
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<errorcode>
23
</errorcode>
diff --git a/tests/data/test2037 b/tests/data/test2037
index d630538e2..84a6676cd 100644
--- a/tests/data/test2037
+++ b/tests/data/test2037
@@ -45,12 +45,11 @@ perl -e "print 'Test requires default test server host' if ( '%HOSTIP' ne '127.0
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
</strip>
<protocol>
GET /2037 HTTP/1.1
Host: localhost:%HTTPSPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2040 b/tests/data/test2040
index ac600174e..cec8a6bcc 100644
--- a/tests/data/test2040
+++ b/tests/data/test2040
@@ -47,17 +47,16 @@ HTTP Basic authorization, then without authorization
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /20400100 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Basic dGVzdHVzZXI6dGVzdHBhc3M=
+User-Agent: curl/%VERSION
Accept: */*
GET /20400200 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2041 b/tests/data/test2041
index 50018e401..d10abaa02 100644
--- a/tests/data/test2041
+++ b/tests/data/test2041
@@ -45,12 +45,10 @@ perl -e "print 'Test requires default test server host' if ( '%HOSTIP' ne '127.0
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2041 HTTP/1.1
Host: localhost:%HTTPSPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2046 b/tests/data/test2046
index ec49c8639..e85c00f23 100644
--- a/tests/data/test2046
+++ b/tests/data/test2046
@@ -59,16 +59,15 @@ http://åäö.se:%HTTPPORT/2046 --resolve xn--4cab6c.se:%HTTPPORT:%HOSTIP -w "%{
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2046 HTTP/1.1
Host: xn--4cab6c.se:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /20460001 HTTP/1.1
Host: xn--4cab6c.se:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2047 b/tests/data/test2047
index 1471d0051..cda2f918e 100644
--- a/tests/data/test2047
+++ b/tests/data/test2047
@@ -61,17 +61,16 @@ http://åäö.se/2047 -x %HOSTIP:%HTTPPORT -w "%{num_connects}\n%{num_redirects}
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://xn--4cab6c.se/2047 HTTP/1.1
Host: xn--4cab6c.se
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://xn--4cab6c.se/20470001 HTTP/1.1
Host: xn--4cab6c.se
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test2049 b/tests/data/test2049
index efa576e98..0653e5900 100644
--- a/tests/data/test2049
+++ b/tests/data/test2049
@@ -38,24 +38,25 @@ http://www1.example.com:8081/2049 --connect-to ::%HOSTIP:%HTTPPORT --next http:/
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2049 HTTP/1.1
Host: www1.example.com:8081
+User-Agent: curl/%VERSION
Accept: */*
GET /2049 HTTP/1.1
Host: www2.example.com:8082
+User-Agent: curl/%VERSION
Accept: */*
GET /2049 HTTP/1.1
Host: www3.example.com:8083
+User-Agent: curl/%VERSION
Accept: */*
GET /2049 HTTP/1.1
Host: www4.example.com:8084
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2050 b/tests/data/test2050
index 5eef3dae2..d4b7e6417 100644
--- a/tests/data/test2050
+++ b/tests/data/test2050
@@ -61,18 +61,17 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<proxy>
CONNECT connect.example.com.2050:%HTTPPORT HTTP/1.1
Host: connect.example.com.2050:%HTTPPORT
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
</proxy>
<protocol>
GET /2050 HTTP/1.1
Host: www.example.com.2050
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2051 b/tests/data/test2051
index e8c6bed1d..97f113800 100644
--- a/tests/data/test2051
+++ b/tests/data/test2051
@@ -38,20 +38,20 @@ http://%HOSTIP:%HTTPPORT/2051 -w "%{num_connects}\n" --next --connect-to ::%HOST
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2051 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /2051 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /2051 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2052 b/tests/data/test2052
index 082002f2c..70549db62 100644
--- a/tests/data/test2052
+++ b/tests/data/test2052
@@ -38,16 +38,15 @@ http://www.example.com:%HTTPPORT/2052 --resolve www.example.com:%HTTPPORT:%HOSTI
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2052 HTTP/1.1
Host: www.example.com:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /2052 HTTP/1.1
Host: www.example.com:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2053 b/tests/data/test2053
index 98e78454e..abf1366cc 100644
--- a/tests/data/test2053
+++ b/tests/data/test2053
@@ -38,16 +38,15 @@ http://10.0.0.1:8081/2053 --connect-to 10.0.0.1:8081:%HOSTIP:%HTTPPORT --next ht
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2053 HTTP/1.1
Host: 10.0.0.1:8081
+User-Agent: curl/%VERSION
Accept: */*
GET /2053 HTTP/1.1
Host: [fc00::1]:8082
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2054 b/tests/data/test2054
index 2a0b54ebc..a79c59ca3 100644
--- a/tests/data/test2054
+++ b/tests/data/test2054
@@ -38,24 +38,25 @@ http://%HOSTIP:%HTTPPORT/2054 --connect-to foo::bar: --connect-to :123::456 --ne
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2054 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /2054 HTTP/1.1
Host: www.example.com:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /2054 HTTP/1.1
Host: %HOSTIP:8083
+User-Agent: curl/%VERSION
Accept: */*
GET /2054 HTTP/1.1
Host: www.example.com:8084
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2055 b/tests/data/test2055
index a5fac62be..5608b81f9 100644
--- a/tests/data/test2055
+++ b/tests/data/test2055
@@ -62,18 +62,17 @@ http://www.example.com.2055/2055 --connect-to ::connect.example.com.2055:%HTTPPO
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<proxy>
CONNECT connect.example.com.2055:%HTTPPORT HTTP/1.1
Host: connect.example.com.2055:%HTTPPORT
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
</proxy>
<protocol>
GET /2055 HTTP/1.1
Host: www.example.com.2055
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2056 b/tests/data/test2056
index 5d2584eec..fc3d14773 100644
--- a/tests/data/test2056
+++ b/tests/data/test2056
@@ -53,13 +53,11 @@ CURL_STUB_GSS_CREDS="KRB5_Alice"
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2056 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Negotiate IktSQjVfQWxpY2UiOkhUVFBAMTI3LjAuMC4xOjE6QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ==
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2057 b/tests/data/test2057
index 92d7824c1..f9c379076 100644
--- a/tests/data/test2057
+++ b/tests/data/test2057
@@ -69,18 +69,17 @@ CURL_STUB_GSS_CREDS="NTLM_Alice"
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2057 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Negotiate Ik5UTE1fQWxpY2UiOkhUVFBAMTI3LjAuMC4xOjI6QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ==
+User-Agent: curl/%VERSION
Accept: */*
GET /2057 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Negotiate Ik5UTE1fQWxpY2UiOkhUVFBAMTI3LjAuMC4xOjM6QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ==
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2058 b/tests/data/test2058
index 613dff001..e1a801466 100644
--- a/tests/data/test2058
+++ b/tests/data/test2058
@@ -81,14 +81,11 @@ test
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://%HOSTIP:%HTTPPORT/2058 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Content-Range: bytes 2-4/5
-User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 0
@@ -97,6 +94,7 @@ GET http://%HOSTIP:%HTTPPORT/2058 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="auser", realm="testrealm", nonce="1053604144", uri="/2058", response="fbed69f9f3fd304c8f1acb1a43eb32688b933c0e28055c16b926cbcec070aeed", algorithm=SHA-256
Content-Range: bytes 2-4/5
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 3
diff --git a/tests/data/test2059 b/tests/data/test2059
index 15799ae07..4b3ed0f50 100644
--- a/tests/data/test2059
+++ b/tests/data/test2059
@@ -81,14 +81,11 @@ test
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://%HOSTIP:%HTTPPORT/2059 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Content-Range: bytes 2-4/5
-User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 0
@@ -97,6 +94,7 @@ GET http://%HOSTIP:%HTTPPORT/2059 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="fddc3bc7b753b73ab0848fd83cb20cbbca971258eb8d20c941dd5e0b010d66be", realm="testrealm", nonce="1053604144", uri="/2059", response="fc09be8192851e284e73e8b719b32a2f6f91cca0594e68713da8c49dc2c1656e", algorithm=SHA-512-256, userhash=true
Content-Range: bytes 2-4/5
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 3
diff --git a/tests/data/test206 b/tests/data/test206
index f99ac4c71..494326495 100644
--- a/tests/data/test206
+++ b/tests/data/test206
@@ -85,22 +85,21 @@ http://test.remote.haxx.se.206:8990/path/2060002 --proxy http://%HOSTIP:%HTTPPOR
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
CONNECT test.remote.haxx.se.206:8990 HTTP/1.1
Host: test.remote.haxx.se.206:8990
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
CONNECT test.remote.haxx.se.206:8990 HTTP/1.1
Host: test.remote.haxx.se.206:8990
Proxy-Authorization: Digest username="silly", realm="weirdorealm", nonce="12345", uri="test.remote.haxx.se.206:8990", response="003e36decb4dbf6366b3ecb9b87c24ec"
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
GET /path/2060002 HTTP/1.1
-User-Agent: curl/7.12.3-CVS (i686-pc-linux-gnu) libcurl/7.12.3-CVS OpenSSL/0.9.6b zlib/1.1.4
Host: test.remote.haxx.se.206:8990
+User-Agent: curl/%VERSION
Accept: */*
[DISCONNECT]
diff --git a/tests/data/test2060 b/tests/data/test2060
index 05ce35103..dfb4bd5b3 100644
--- a/tests/data/test2060
+++ b/tests/data/test2060
@@ -81,14 +81,11 @@ test
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://%HOSTIP:%HTTPPORT/2060 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Content-Range: bytes 2-4/5
-User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 0
@@ -97,6 +94,7 @@ GET http://%HOSTIP:%HTTPPORT/2060 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="auser", realm="testrealm", nonce="1053604144", uri="/2060", response="3ce1e25ffa611bdbe90e2ab367b9602fa223db9f6de76ac667f0d6157e2178a6", algorithm=SHA-512-256
Content-Range: bytes 2-4/5
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 3
diff --git a/tests/data/test2061 b/tests/data/test2061
index bee88e34a..6953423a3 100644
--- a/tests/data/test2061
+++ b/tests/data/test2061
@@ -65,18 +65,16 @@ http://%HOSTIP:%HTTPPORT/2061 -u testuser:testpass --digest
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2061 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /2061 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="testrealm", nonce="1053604145", uri="/2061", response="9dc55255f1a2537b838311674b621d45346b862a81631bb20e4ce356ef25062d", algorithm=SHA-256
-User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2062 b/tests/data/test2062
index f6d4aff24..6075263de 100644
--- a/tests/data/test2062
+++ b/tests/data/test2062
@@ -65,18 +65,16 @@ http://%HOSTIP:%HTTPPORT/2062 -u testuser:testpass --digest
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2062 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /2062 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="testrealm", nonce="1053604145", uri="/2062", response="2af735ec3508f4dff99248ffbbe9de9002bfd7cc770cfa2b026cb334042a54e3", algorithm=SHA-512-256
-User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2063 b/tests/data/test2063
index af9a9f0aa..557e59361 100644
--- a/tests/data/test2063
+++ b/tests/data/test2063
@@ -65,18 +65,16 @@ http://%HOSTIP:%HTTPPORT/2063 -u testuser:testpass --digest
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2063 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /2063 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="75af8a3500f771e58a52093a25e7905d6e428a511285c12ea1420c73078dfd61", realm="testrealm", nonce="1053604145", uri="/2063", response="43f7ab531dff687b5dc75617daa59d1fd67d648341d6d2655ca65ef5064cfb51", algorithm=SHA-512-256, userhash=true
-User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2064 b/tests/data/test2064
index bfaaa05e8..fc196f258 100644
--- a/tests/data/test2064
+++ b/tests/data/test2064
@@ -65,18 +65,16 @@ http://%HOSTIP:%HTTPPORT/2064 -u testuser:test2pass --digest
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2064 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /2064 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="testrealm", nonce="2053604145", uri="/2064", response="a9c3ec1036068b336cbabefe9dfcad52ee8b89bc7c91ddbb5bb415c6acdf38a5", algorithm=SHA-256
-User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2065 b/tests/data/test2065
index d18b008ad..f352e6bcc 100644
--- a/tests/data/test2065
+++ b/tests/data/test2065
@@ -65,18 +65,16 @@ http://%HOSTIP:%HTTPPORT/2065 -u testuser:test2pass --digest
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2065 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /2065 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="testrealm", nonce="2053604145", uri="/2065", response="5a5f20b0e601aeddc6f96422c2332d49ff431c49ab143b5f836ef76e9ac78f5e", algorithm=SHA-512-256
-User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2066 b/tests/data/test2066
index b6effee0e..31a143d69 100644
--- a/tests/data/test2066
+++ b/tests/data/test2066
@@ -65,18 +65,16 @@ http://%HOSTIP:%HTTPPORT/2066 -u testuser:test2pass --digest
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2066 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /2066 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="75af8a3500f771e58a52093a25e7905d6e428a511285c12ea1420c73078dfd61", realm="testrealm", nonce="2053604145", uri="/2066", response="a2e2ae589f575fb132991d6f550ef14bf7ef697d2fef1242d2498f07eafc77dc", algorithm=SHA-512-256, userhash=true
-User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2067 b/tests/data/test2067
index c203343e6..0ae407606 100644
--- a/tests/data/test2067
+++ b/tests/data/test2067
@@ -66,12 +66,10 @@ HTTP POST --digest with SHA256 and user-specified Content-Length header
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /2067 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
@@ -79,6 +77,7 @@ Content-Type: application/x-www-form-urlencoded
POST /2067 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="auser", realm="testrealm", nonce="1053604144", uri="/2067", response="67b97af219c92fa7e8685e5bebb8e74892f6c6792e911c52bd2dfbf0b49272eb", algorithm=SHA-256
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 11
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test2068 b/tests/data/test2068
index 5a197ce27..21003bdb2 100644
--- a/tests/data/test2068
+++ b/tests/data/test2068
@@ -66,12 +66,10 @@ HTTP POST --digest with SHA-512-256, userhash=false and user-specified Content-L
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /2068 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
@@ -79,6 +77,7 @@ Content-Type: application/x-www-form-urlencoded
POST /2068 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="auser", realm="testrealm", nonce="1053604144", uri="/2068", response="4bc9c97a72f1856bcec9b0e1518c6b7ee28773f91357d56840bdc30bd89ca68f", algorithm=SHA-512-256
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 11
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test2069 b/tests/data/test2069
index 99fd71d0e..fb3d15dcd 100644
--- a/tests/data/test2069
+++ b/tests/data/test2069
@@ -66,12 +66,10 @@ HTTP POST --digest with SHA-512-256, userhash=true and user-specified Content-Le
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /2069 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
@@ -79,6 +77,7 @@ Content-Type: application/x-www-form-urlencoded
POST /2069 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="fddc3bc7b753b73ab0848fd83cb20cbbca971258eb8d20c941dd5e0b010d66be", realm="testrealm", nonce="1053604144", uri="/2069", response="ff13d977110a471f30de75e747976e4de78d7a3d2425cd23ff46e67f4bc9ead7", algorithm=SHA-512-256, userhash=true
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 11
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test207 b/tests/data/test207
index caff81057..1ce2338a3 100644
--- a/tests/data/test207
+++ b/tests/data/test207
@@ -48,12 +48,10 @@ http://%HOSTIP:%HTTPPORT/207
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /207 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2070 b/tests/data/test2070
index f03c87b49..1039e84a5 100644
--- a/tests/data/test2070
+++ b/tests/data/test2070
@@ -49,12 +49,10 @@ perl -e "print 'Test requires default test server host' if ( '%HOSTIP' ne '127.0
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2070 HTTP/1.1
Host: localhost:%HTTPSPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2073 b/tests/data/test2073
index ed942f018..160ddbbcb 100644
--- a/tests/data/test2073
+++ b/tests/data/test2073
@@ -42,11 +42,12 @@ http://%HOSTIP:%HTTPPORT/2073 -F 'name=a;filename=a.pdf' --next http://%HOSTIP:%
# Verify data after the test has been "shot"
<verify>
<strip>
-^(User-Agent:|Content-Type: multipart/form-data;|------------).*
+^(Content-Type: multipart/form-data;|------------).*
</strip>
<protocol>
POST /2073 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 189
@@ -56,6 +57,7 @@ Content-Type: application/pdf
a
POST /2073 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 184
diff --git a/tests/data/test2074 b/tests/data/test2074
index ecff8fe7e..e3e18126c 100644
--- a/tests/data/test2074
+++ b/tests/data/test2074
@@ -43,13 +43,11 @@ http://%HOSTIP:%HTTPPORT/2074 --oauth2-bearer mF_9.B5f-4.1JqM
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2074 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Bearer mF_9.B5f-4.1JqM
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2076 b/tests/data/test2076
index 2c477b1a5..5974286f6 100644
--- a/tests/data/test2076
+++ b/tests/data/test2076
@@ -57,17 +57,16 @@ HTTP with digest auth and URI contains query
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /2076?query HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /2076?query HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="testrealm", nonce="1", uri="/2076?query", response="5758bd3bbde7f33236e6ccd278eb59af"
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2078 b/tests/data/test2078
index 51ace296a..c881b0499 100644
--- a/tests/data/test2078
+++ b/tests/data/test2078
@@ -38,12 +38,10 @@ http://%HOSTIP:%HTTPPORT/2078 -u : --negotiate --data name=value
<errorcode>
0
</errorcode>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /2078 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 10
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test208 b/tests/data/test208
index 1c86558a8..abb30df97 100644
--- a/tests/data/test208
+++ b/tests/data/test208
@@ -50,13 +50,11 @@ the
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT ftp://daniel:mysecret@host.com/we/want/208 HTTP/1.1
Host: host.com:21
Authorization: Basic ZGFuaWVsOm15c2VjcmV0
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 78
diff --git a/tests/data/test209 b/tests/data/test209
index 67a7fc513..afe16bfa6 100644
--- a/tests/data/test209
+++ b/tests/data/test209
@@ -101,23 +101,22 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
CONNECT test.remote.example.com.209:%HTTPPORT HTTP/1.1
Host: test.remote.example.com.209:%HTTPPORT
Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
CONNECT test.remote.example.com.209:%HTTPPORT HTTP/1.1
Host: test.remote.example.com.209:%HTTPPORT
Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAADj3hs3u3j0kgJqCrLM+74BmaoNHDfIJjHRlc3R1c2VyY3VybGhvc3Q=
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
GET /path/2090002 HTTP/1.1
-User-Agent: curl/7.12.3-CVS (i686-pc-linux-gnu) libcurl/7.12.3-CVS OpenSSL/0.9.6b zlib/1.1.4
Host: test.remote.example.com.209:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test2100 b/tests/data/test2100
index 83aa7287b..4352f61b4 100644
--- a/tests/data/test2100
+++ b/tests/data/test2100
Binary files differ
diff --git a/tests/data/test213 b/tests/data/test213
index e6d7cd55a..bb579971d 100644
--- a/tests/data/test213
+++ b/tests/data/test213
@@ -101,23 +101,22 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol nonewline="yes">
CONNECT test.remote.example.com.213:%HTTPPORT HTTP/1.0
Host: test.remote.example.com.213:%HTTPPORT
Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
CONNECT test.remote.example.com.213:%HTTPPORT HTTP/1.0
Host: test.remote.example.com.213:%HTTPPORT
Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAADj3hs3u3j0kgJqCrLM+74BmaoNHDfIJjHRlc3R1c2VyY3VybGhvc3Q=
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
POST /path/2130002 HTTP/1.1
-User-Agent: curl/7.12.3-CVS (i686-pc-linux-gnu) libcurl/7.12.3-CVS OpenSSL/0.9.6b zlib/1.1.4
Host: test.remote.example.com.213:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 6
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test214 b/tests/data/test214
index 930182f5d..3f305ee19 100644
--- a/tests/data/test214
+++ b/tests/data/test214
@@ -40,12 +40,10 @@ MSYS2_ARG_CONV_EXCL=http://
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /{}\/214 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test217 b/tests/data/test217
index 4ab51a2f3..b06734473 100644
--- a/tests/data/test217
+++ b/tests/data/test217
@@ -41,12 +41,10 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
CONNECT test.remote.example.com.217:%HTTPPORT HTTP/1.1
Host: test.remote.example.com.217:%HTTPPORT
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
</protocol>
diff --git a/tests/data/test218 b/tests/data/test218
index 138c4b7b1..4951c264b 100644
--- a/tests/data/test218
+++ b/tests/data/test218
@@ -39,12 +39,10 @@ just some tiny teeny contents
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /218 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Transfer-Encoding: chunked
Expect: 100-continue
diff --git a/tests/data/test22 b/tests/data/test22
index f45f8627c..57dd7ddaa 100644
--- a/tests/data/test22
+++ b/tests/data/test22
@@ -32,13 +32,10 @@ get HTTP with URL > 10000 bytes
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
GET /aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/22 HTTP/1.1
-User-Agent: curl/7.4.2 (sparc-sun-solaris2.7) libcurl 7.4.2 (SSL 0.9.6)
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test220 b/tests/data/test220
index 7fd264345..4b2e41672 100644
--- a/tests/data/test220
+++ b/tests/data/test220
@@ -54,15 +54,13 @@ http://%HOSTIP:%HTTPPORT/220 --compressed
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<strippart>
s/^Accept-Encoding: .*/Accept-Encoding: xxx/
</strippart>
<protocol>
GET /220 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Accept-Encoding: xxx
diff --git a/tests/data/test221 b/tests/data/test221
index 3a85439d0..3fab37f52 100644
--- a/tests/data/test221
+++ b/tests/data/test221
@@ -54,15 +54,13 @@ http://%HOSTIP:%HTTPPORT/221 --compressed
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<strippart>
s/^Accept-Encoding: .*/Accept-Encoding: xxx/
</strippart>
<protocol>
GET /221 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Accept-Encoding: xxx
diff --git a/tests/data/test222 b/tests/data/test222
index 865266e07..27d169fed 100644
--- a/tests/data/test222
+++ b/tests/data/test222
@@ -185,15 +185,13 @@ http://%HOSTIP:%HTTPPORT/222 --compressed
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<strippart>
s/^Accept-Encoding: .*/Accept-Encoding: xxx/
</strippart>
<protocol>
GET /222 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Accept-Encoding: xxx
diff --git a/tests/data/test223 b/tests/data/test223
index 884967e3f..52bbb7c6f 100644
--- a/tests/data/test223
+++ b/tests/data/test223
@@ -75,15 +75,13 @@ http://%HOSTIP:%HTTPPORT/223 --compressed
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<strippart>
s/^Accept-Encoding: .*/Accept-Encoding: xxx/
</strippart>
<protocol>
GET /223 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Accept-Encoding: xxx
diff --git a/tests/data/test224 b/tests/data/test224
index a56046873..b632ffd29 100644
--- a/tests/data/test224
+++ b/tests/data/test224
@@ -90,15 +90,13 @@ http://%HOSTIP:%HTTPPORT/224 --compressed
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<strippart>
s/^Accept-Encoding: .*/Accept-Encoding: xxx/
</strippart>
<protocol>
GET /224 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Accept-Encoding: xxx
diff --git a/tests/data/test230 b/tests/data/test230
index 2174434b3..eb696da02 100644
--- a/tests/data/test230
+++ b/tests/data/test230
@@ -186,15 +186,13 @@ http://%HOSTIP:%HTTPPORT/230 --compressed
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<strippart>
s/^Accept-Encoding: .*/Accept-Encoding: xxx/
</strippart>
<protocol>
GET /230 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Accept-Encoding: xxx
diff --git a/tests/data/test232 b/tests/data/test232
index d0860c616..e0e703422 100644
--- a/tests/data/test232
+++ b/tests/data/test232
@@ -185,15 +185,13 @@ http://%HOSTIP:%HTTPPORT/232 --compressed
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<strippart>
s/^Accept-Encoding: .*/Accept-Encoding: xxx/
</strippart>
<protocol>
GET /232 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Accept-Encoding: xxx
diff --git a/tests/data/test233 b/tests/data/test233
index a38d8c95e..eb732eae6 100644
--- a/tests/data/test233
+++ b/tests/data/test233
@@ -75,20 +75,19 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://first.host.it.is/we/want/that/page/233 HTTP/1.1
Host: first.host.it.is
Proxy-Authorization: Basic dGVzdGluZzp0aGlz
Authorization: Basic aWFtOm15c2VsZg==
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://goto.second.host.now/2330002 HTTP/1.1
Host: goto.second.host.now
Proxy-Authorization: Basic dGVzdGluZzp0aGlz
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test234 b/tests/data/test234
index 9e197cd1d..3c5146a37 100644
--- a/tests/data/test234
+++ b/tests/data/test234
@@ -77,14 +77,12 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://first.host.it.is/we/want/that/page/234 HTTP/1.1
Host: first.host.it.is
Proxy-Authorization: Basic dGVzdGluZzp0aGlz
Authorization: Basic aWFtOm15c2VsZg==
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
@@ -92,6 +90,7 @@ GET http://goto.second.host.now/2340002 HTTP/1.1
Host: goto.second.host.now
Proxy-Authorization: Basic dGVzdGluZzp0aGlz
Authorization: Basic aWFtOm15c2VsZg==
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test235 b/tests/data/test235
index 625023221..94abb951c 100644
--- a/tests/data/test235
+++ b/tests/data/test235
@@ -7,6 +7,9 @@ FTP
# Server-side
<reply>
+<servercmd>
+REPLY SIZE 500 command not understood
+</servercmd>
</reply>
# Client-side
diff --git a/tests/data/test236 b/tests/data/test236
index 9ba706f1d..92e34bc3e 100644
--- a/tests/data/test236
+++ b/tests/data/test236
@@ -11,6 +11,7 @@ FTP
REPLY SIZE 550 access to this file is very much denied
REPLY APPE 550 I said: access to this file is very much denied
REPLY STOR 550 I said: access to this file is very much denied
+REPLY SIZE 500 command not understood
</servercmd>
</reply>
diff --git a/tests/data/test239 b/tests/data/test239
index b6f387933..b9e187235 100644
--- a/tests/data/test239
+++ b/tests/data/test239
@@ -76,14 +76,11 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol nonewline="yes">
POST http://%HOSTIP:%HTTPPORT/239 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 0
@@ -92,7 +89,7 @@ Content-Type: application/x-www-form-urlencoded
POST http://%HOSTIP:%HTTPPORT/239 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAADj3hs3u3j0kgJqCrLM+74BmaoNHDfIJjHRlc3R1c2VyY3VybGhvc3Q=
-User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 6
diff --git a/tests/data/test24 b/tests/data/test24
index a2b28a9fd..54147eddf 100644
--- a/tests/data/test24
+++ b/tests/data/test24
@@ -30,13 +30,10 @@ http://%HOSTIP:%HTTPPORT/24 --fail --silent --show-error
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
GET /24 HTTP/1.1
-User-Agent: curl/7.8.1-pre3 (sparc-sun-solaris2.7) libcurl 7.8.1-pre3 (OpenSSL 0.9.6a) (krb4 enabled)
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test240 b/tests/data/test240
index cd8594d63..0d452ee25 100644
--- a/tests/data/test240
+++ b/tests/data/test240
@@ -45,12 +45,10 @@ HTTP-IPv6 GET
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:
-</strip>
<protocol>
GET /240 HTTP/1.1
Host: %HOST6IP:%HTTP6PORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test241 b/tests/data/test241
index 46eae1f72..e530aaff5 100644
--- a/tests/data/test241
+++ b/tests/data/test241
@@ -43,12 +43,10 @@ HTTP-IPv6 GET (using ip6-localhost)
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:
-</strip>
<protocol>
GET /241 HTTP/1.1
Host: ip6-localhost:%HTTP6PORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test242 b/tests/data/test242
index 9457c58c3..aee927ea7 100644
--- a/tests/data/test242
+++ b/tests/data/test242
@@ -40,13 +40,11 @@ HTTP-IPv6 GET with username+password in URL
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:
-</strip>
<protocol>
GET /242 HTTP/1.1
Host: %HOST6IP:%HTTP6PORT
Authorization: Basic Zm9vYmFyOmJhcmZvbw==
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test243 b/tests/data/test243
index f7b2386b5..87826a82e 100644
--- a/tests/data/test243
+++ b/tests/data/test243
@@ -97,13 +97,10 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol nonewline="yes">
POST http://%HOSTIP:%HTTPPORT/243 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
-User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 6
@@ -112,7 +109,7 @@ Content-Type: application/x-www-form-urlencoded
postitPOST http://%HOSTIP:%HTTPPORT/243 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 0
@@ -121,7 +118,7 @@ Content-Type: application/x-www-form-urlencoded
POST http://%HOSTIP:%HTTPPORT/243 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAADj3hs3u3j0kgJqCrLM+74BmaoNHDfIJjHRlc3R1c2VyY3VybGhvc3Q=
-User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 6
diff --git a/tests/data/test245 b/tests/data/test245
index cbb5ee31d..5750b4fa3 100644
--- a/tests/data/test245
+++ b/tests/data/test245
@@ -63,13 +63,10 @@ http://%HOSTIP:%HTTPPORT/245 -u auser:apasswd --digest -d "junkelijunk"
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /245 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
-User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
@@ -77,7 +74,7 @@ Content-Type: application/x-www-form-urlencoded
POST /245 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="auser", realm="testrealm", nonce="1053604144", uri="/245", response="379a439b1737ba257c1d2f103914b18b"
-User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 11
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test246 b/tests/data/test246
index acf47da5d..b5469f3e5 100644
--- a/tests/data/test246
+++ b/tests/data/test246
@@ -73,13 +73,10 @@ http://%HOSTIP:%HTTPPORT/246 -u auser:apasswd --digest -d "junkelijunk"
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /246 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
-User-Agent: curl/7.12.1-CVS (i686-pc-linux-gnu) libcurl/7.12.1-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.6
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
@@ -87,7 +84,7 @@ Content-Type: application/x-www-form-urlencoded
POST /246 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="auser", realm="testrealm", nonce="1053604144", uri="/246", response="761e6fc9a760c39d587092e8d840e740"
-User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 11
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test249 b/tests/data/test249
index 4f99c2af7..6b3dc6ef1 100644
--- a/tests/data/test249
+++ b/tests/data/test249
@@ -39,12 +39,10 @@ http://%HOSTIP:%HTTPPORT/249 -z "dec 12 12:00:00 1999 GMT"
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /249 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
If-Modified-Since: Sun, 12 Dec 1999 12:00:00 GMT
diff --git a/tests/data/test25 b/tests/data/test25
index 15030ae92..d694cdc75 100644
--- a/tests/data/test25
+++ b/tests/data/test25
@@ -73,38 +73,35 @@ http://%HOSTIP:%HTTPPORT/want/25 -L --max-redirs 5
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
GET /want/25 HTTP/1.1
-User-Agent: curl/7.8.1-pre3 (sparc-sun-solaris2.7) libcurl 7.8.1-pre3 (OpenSSL 0.9.6a) (krb4 enabled)
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /want/data/reply/25 HTTP/1.1
-User-Agent: curl/7.8.1-pre3 (sparc-sun-solaris2.7) libcurl 7.8.1-pre3 (OpenSSL 0.9.6a) (krb4 enabled)
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /want/data/reply/data/reply/25 HTTP/1.1
-User-Agent: curl/7.8.1-pre3 (sparc-sun-solaris2.7) libcurl 7.8.1-pre3 (OpenSSL 0.9.6a) (krb4 enabled)
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /want/data/reply/data/reply/data/reply/25 HTTP/1.1
-User-Agent: curl/7.8.1-pre3 (sparc-sun-solaris2.7) libcurl 7.8.1-pre3 (OpenSSL 0.9.6a) (krb4 enabled)
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /want/data/reply/data/reply/data/reply/data/reply/25 HTTP/1.1
-User-Agent: curl/7.8.1-pre3 (sparc-sun-solaris2.7) libcurl 7.8.1-pre3 (OpenSSL 0.9.6a) (krb4 enabled)
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /want/data/reply/data/reply/data/reply/data/reply/data/reply/25 HTTP/1.1
-User-Agent: curl/7.8.1-pre3 (sparc-sun-solaris2.7) libcurl 7.8.1-pre3 (OpenSSL 0.9.6a) (krb4 enabled)
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test256 b/tests/data/test256
index 1567c6292..e873d579c 100644
--- a/tests/data/test256
+++ b/tests/data/test256
@@ -45,14 +45,12 @@ proxy
<errorcode>
33
</errorcode>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://%HOSTIP:%HTTPPORT/want/256 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Proxy-Authorization: Basic ZGFuaWVsOnN0ZW5iZXJn
Range: bytes=78-
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test257 b/tests/data/test257
index 59a419bb1..e43baf56e 100644
--- a/tests/data/test257
+++ b/tests/data/test257
@@ -85,27 +85,24 @@ machine anotherone.com login user2 password passwd2
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://supersite.com/want/257 HTTP/1.1
Host: supersite.com
Authorization: Basic dXNlcjE6cGFzc3dkMQ==
-User-Agent: curl/7.14.0-CVS (i686-pc-linux-gnu) libcurl/7.14.0-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://anotherone.com/2570002 HTTP/1.1
Host: anotherone.com
Authorization: Basic dXNlcjI6cGFzc3dkMg==
-User-Agent: curl/7.14.0-CVS (i686-pc-linux-gnu) libcurl/7.14.0-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://athird.com/2570003 HTTP/1.1
Host: athird.com
-User-Agent: curl/7.14.0-CVS (i686-pc-linux-gnu) libcurl/7.14.0-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test258 b/tests/data/test258
index 6c10564b8..c89d5f37e 100644
--- a/tests/data/test258
+++ b/tests/data/test258
@@ -77,12 +77,12 @@ bar
# Verify data after the test has been "shot"
<verify>
<strip>
-^(User-Agent:|Content-Type: multipart/form-data;|------).*
+^(Content-Type: multipart/form-data;|------).*
</strip>
<protocol>
POST http://remotehost:54321/we/want/258 HTTP/1.1
Host: remotehost:54321
-User-Agent: curl/7.10.4 (i686-pc-linux-gnu) libcurl/7.10.4 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 409
@@ -107,8 +107,8 @@ bar
------------------------------7c633d5c27ce--
POST http://remotehost:54321/we/want/258 HTTP/1.1
Host: remotehost:54321
-User-Agent: curl/7.10.4 (i686-pc-linux-gnu) libcurl/7.10.4 OpenSSL/0.9.7a ipv6 zlib/1.1.3
Proxy-Authorization: Digest username="uuuser", realm="many secrets", nonce="911", uri="/we/want/258", response="2501654ca391f0b5c8c12a1da77e34cd"
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 409
diff --git a/tests/data/test259 b/tests/data/test259
index 58d25120f..d1da02432 100644
--- a/tests/data/test259
+++ b/tests/data/test259
@@ -73,12 +73,12 @@ bar
# Verify data after the test has been "shot"
<verify>
<strip>
-^(User-Agent:|Content-Type: multipart/form-data;|------).*
+^(Content-Type: multipart/form-data;|------).*
</strip>
<protocol>
POST http://remotehost:54321/we/want/259 HTTP/1.1
Host: remotehost:54321
-User-Agent: curl/7.10.4 (i686-pc-linux-gnu) libcurl/7.10.4 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Expect: 100-continue
@@ -104,8 +104,8 @@ bar
------------------------------7c633d5c27ce--
POST http://remotehost:54321/we/want/259 HTTP/1.1
Host: remotehost:54321
-User-Agent: curl/7.10.4 (i686-pc-linux-gnu) libcurl/7.10.4 OpenSSL/0.9.7a ipv6 zlib/1.1.3
Proxy-Authorization: Digest username="uuuser", realm="many secrets", nonce="911", uri="/we/want/259", response="b479994d13e60f3aa192a67c5892ddc5"
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Expect: 100-continue
diff --git a/tests/data/test26 b/tests/data/test26
index 072dbf7d3..073fed3d3 100644
--- a/tests/data/test26
+++ b/tests/data/test26
@@ -31,13 +31,10 @@ http://%HOSTIP:%HTTPPORT/want/26 -o - -o -
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl.*
-</strip>
<protocol>
GET /want/26 HTTP/1.1
-User-Agent: curl/7.8.1-pre3 (sparc-sun-solaris2.7) libcurl 7.8.1-pre3 (OpenSSL 0.9.6a) (krb4 enabled)
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test260 b/tests/data/test260
index 589e86e8a..1e6dbe2e0 100644
--- a/tests/data/test260
+++ b/tests/data/test260
@@ -42,12 +42,10 @@ HTTP GET URL without slash but with questionmark
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /?260 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test262 b/tests/data/test262
index 4c28f22d7..8f803cfbf 100644
--- a/tests/data/test262
+++ b/tests/data/test262
Binary files differ
diff --git a/tests/data/test263 b/tests/data/test263
index e10c20741..6c054a11d 100644
--- a/tests/data/test263
+++ b/tests/data/test263
@@ -41,12 +41,10 @@ HTTP-IPv6 GET with proxy specified using IPv6-numerical address
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:
-</strip>
<protocol>
GET http://veryveryremotesite.com/263 HTTP/1.1
Host: veryveryremotesite.com
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test264 b/tests/data/test264
index 5aca0e6c5..836c979a6 100644
--- a/tests/data/test264
+++ b/tests/data/test264
@@ -37,13 +37,11 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://we.want.that.site.com/264 HTTP/1.1
Host: we.want.that.site.com
Proxy-Authorization: Basic ZmFrZTp1c2Vy
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test265 b/tests/data/test265
index a27633afc..c62047303 100644
--- a/tests/data/test265
+++ b/tests/data/test265
@@ -102,23 +102,22 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol nonewline="yes">
CONNECT test.remote.example.com.265:%HTTPPORT HTTP/1.1
Host: test.remote.example.com.265:%HTTPPORT
Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
CONNECT test.remote.example.com.265:%HTTPPORT HTTP/1.1
Host: test.remote.example.com.265:%HTTPPORT
Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAADj3hs3u3j0kgJqCrLM+74BmaoNHDfIJjHRlc3R1c2VyY3VybGhvc3Q=
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
POST /path/2650002 HTTP/1.1
-User-Agent: curl/7.12.3-CVS (i686-pc-linux-gnu) libcurl/7.12.3-CVS OpenSSL/0.9.6b zlib/1.1.4
Host: test.remote.example.com.265:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 6
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test266 b/tests/data/test266
index 6b07a782b..0997ae7b6 100644
--- a/tests/data/test266
+++ b/tests/data/test266
@@ -56,12 +56,10 @@ http://%HOSTIP:%HTTPPORT/266 -D log/heads266
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /266 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test267 b/tests/data/test267
index a0c3d33c6..ed10b22a3 100644
--- a/tests/data/test267
+++ b/tests/data/test267
@@ -82,14 +82,11 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /267 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
Header1: yes
Header2: no
@@ -99,7 +96,7 @@ Content-Type: application/x-www-form-urlencoded
POST /267 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAADj3hs3u3j0kgJqCrLM+74BmaoNHDfIJjHRlc3R1c2VyY3VybGhvc3Q=
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
Header1: yes
Header2: no
diff --git a/tests/data/test268 b/tests/data/test268
index c9c7311ab..70a5a73dd 100644
--- a/tests/data/test268
+++ b/tests/data/test268
@@ -42,12 +42,10 @@ HTTP POST a non-existing file
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
POST /268 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test269 b/tests/data/test269
index 6b7159b0b..ffecfedbf 100644
--- a/tests/data/test269
+++ b/tests/data/test269
@@ -40,12 +40,10 @@ http://%HOSTIP:%HTTPPORT/269 --ignore-content-length
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /269 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test27 b/tests/data/test27
index 6fed3d994..54b4f8a62 100644
--- a/tests/data/test27
+++ b/tests/data/test27
@@ -33,21 +33,21 @@ Get same cookie page several times
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl.*
-</strip>
<protocol>
GET /want/27 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /want/27 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Cookie: thewinneris=nowayyouwin
GET /want/27 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Cookie: thewinneris=nowayyouwin
diff --git a/tests/data/test273 b/tests/data/test273
index ce0be331e..45c293512 100644
--- a/tests/data/test273
+++ b/tests/data/test273
@@ -65,18 +65,16 @@ http://%HOSTIP:%HTTPPORT/273 -u testuser:testpass --digest
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /273 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /273 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="testrealm", nonce="1053604145", uri="/273", response="576ae57b1db0039f8c0de43ef58e49e3"
-User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test274 b/tests/data/test274
index 579341c82..dd1b816de 100644
--- a/tests/data/test274
+++ b/tests/data/test274
@@ -34,13 +34,10 @@ http://%HOSTIP:%HTTPPORT/want/274 -L --max-redirs 0
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
GET /want/274 HTTP/1.1
-User-Agent: curl/7.8.1-pre3 (sparc-sun-solaris2.7) libcurl 7.8.1-pre3 (OpenSSL 0.9.6a) (krb4 enabled)
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test275 b/tests/data/test275
index 6065b4d81..cff99d588 100644
--- a/tests/data/test275
+++ b/tests/data/test275
@@ -64,14 +64,11 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<proxy>
CONNECT remotesite.com.275:%HTTPPORT HTTP/1.1
Host: remotesite.com.275:%HTTPPORT
Proxy-Authorization: Basic eW91YXJlOnlvdXJzZWxm
-User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
</proxy>
@@ -79,11 +76,13 @@ Proxy-Connection: Keep-Alive
GET /we/want/that/page/275 HTTP/1.1
Host: remotesite.com.275:%HTTPPORT
Authorization: Basic aWFtOm15c2VsZg==
+User-Agent: curl/%VERSION
Accept: */*
GET /we/want/that/page/275 HTTP/1.1
Host: remotesite.com.275:%HTTPPORT
Authorization: Basic aWFtOm15c2VsZg==
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test276 b/tests/data/test276
index 34e2235e1..2fa554d9d 100644
--- a/tests/data/test276
+++ b/tests/data/test276
@@ -59,16 +59,15 @@ HTTP Location: following with multiple question marks in URLs
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want?uri=http://anything/276?secondq/276 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /data/2760002.txt?coolsite=http://anotherurl/?a_second/2760002 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test277 b/tests/data/test277
index d3e9d0fa4..7b60d40ea 100644
--- a/tests/data/test277
+++ b/tests/data/test277
@@ -33,17 +33,14 @@ http://%HOSTIP:%HTTPPORT/want/277 -F name=daniel -H "Content-Type: text/info"
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<strippart>
s/^--------------------------[a-z0-9]*/--------------------------/
s/boundary=------------------------[a-z0-9]*/boundary=------------------------/
</strippart>
<protocol>
POST /want/277 HTTP/1.1
-User-Agent: curl/7.10.4 (i686-pc-linux-gnu) libcurl/7.10.4 OpenSSL/0.9.7a ipv6 zlib/1.1.3
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 146
Content-Type: text/info; boundary=------------------------
diff --git a/tests/data/test278 b/tests/data/test278
index 620f56b17..d706c33ce 100644
--- a/tests/data/test278
+++ b/tests/data/test278
@@ -37,13 +37,11 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://we.want.that.site.com/278 HTTP/1.1
Host: we.want.that.site.com
Proxy-Authorization: Basic ZmFrZTo=
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test279 b/tests/data/test279
index d5f4194f1..d26ddd9d8 100644
--- a/tests/data/test279
+++ b/tests/data/test279
@@ -38,13 +38,11 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://we.want.that.site.com/279 HTTP/1.1
Host: we.want.that.site.com
Proxy-Authorization: Basic ZmFrZTo=
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test28 b/tests/data/test28
index 1f80d5f48..703c6d35b 100644
--- a/tests/data/test28
+++ b/tests/data/test28
@@ -58,16 +58,15 @@ http://%HOSTIP:%HTTPPORT/want/28 -L
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/28 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /online/1,1795,Welcome,00.html/280002.txt?logout=TRUE HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test281 b/tests/data/test281
index d399fc05b..f78b0c146 100644
--- a/tests/data/test281
+++ b/tests/data/test281
@@ -46,12 +46,10 @@ Weird
<errorcode>
22
</errorcode>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /we/want/281 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 38
Expect: 100-continue
diff --git a/tests/data/test282 b/tests/data/test282
index aa8aba5a2..578c102a5 100644
--- a/tests/data/test282
+++ b/tests/data/test282
@@ -32,12 +32,10 @@ http://%HOSTIP:%HTTPPORT/282
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /282 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test29 b/tests/data/test29
index 9a7bd9ef9..b8a59c34a 100644
--- a/tests/data/test29
+++ b/tests/data/test29
@@ -36,12 +36,10 @@ http://%HOSTIP:%HTTPPORT/want/29 -m 2
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/29 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test292 b/tests/data/test292
index 800e8d178..12d131dbf 100644
--- a/tests/data/test292
+++ b/tests/data/test292
@@ -43,12 +43,10 @@ http://%HOSTIP:%HTTPPORT/292 --max-filesize 1000
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /292 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test293 b/tests/data/test293
index d75fc9a3c..2181a8216 100644
--- a/tests/data/test293
+++ b/tests/data/test293
@@ -47,12 +47,10 @@ http://%HOSTIP:%HTTPPORT/293 --max-filesize 2
<errorcode>
63
</errorcode>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /293 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test299 b/tests/data/test299
index cfa743020..b3fa47361 100644
--- a/tests/data/test299
+++ b/tests/data/test299
@@ -39,13 +39,11 @@ FTP over HTTP proxy with user:pass not in url
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET ftp://michal:aybabtu@host.com/we/want/299 HTTP/1.1
Host: host.com:21
Authorization: Basic bWljaGFsOmF5YmFidHU=
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test3 b/tests/data/test3
index 0fe276467..0dc3b4618 100644
--- a/tests/data/test3
+++ b/tests/data/test3
@@ -43,13 +43,11 @@ HTTP POST with auth and contents but with content-length set to 0
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /3 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Basic ZmFrZTotdXNlcg==
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 37
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test30 b/tests/data/test30
index 70b8005f5..ab4425db5 100644
--- a/tests/data/test30
+++ b/tests/data/test30
@@ -27,12 +27,10 @@ http://%HOSTIP:%HTTPPORT/want/30
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/30 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test300 b/tests/data/test300
index 7b4222d12..63e308d6d 100644
--- a/tests/data/test300
+++ b/tests/data/test300
@@ -39,12 +39,10 @@ simple HTTPS GET
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /300 HTTP/1.1
Host: %HOSTIP:%HTTPSPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test3000 b/tests/data/test3000
index e62e53168..1fc58f2f3 100644
--- a/tests/data/test3000
+++ b/tests/data/test3000
@@ -44,12 +44,10 @@ perl -e "print 'Test requires default test server host' if ( '%HOSTIP' ne '127.0
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /3000 HTTP/1.1
Host: localhost:%HTTPSPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test3001 b/tests/data/test3001
index 706c3f752..a16bdb45a 100644
--- a/tests/data/test3001
+++ b/tests/data/test3001
@@ -44,12 +44,10 @@ perl -e "print 'Test requires default test server host' if ( '%HOSTIP' ne '127.0
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /3001 HTTP/1.1
Host: localhost:%HTTPSPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test3008 b/tests/data/test3008
new file mode 100644
index 000000000..0010eeb86
--- /dev/null
+++ b/tests/data/test3008
@@ -0,0 +1,57 @@
+<testcase>
+<info>
+<keywords>
+-O
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+<features>
+http
+</features>
+<name>
+--output-dir
+</name>
+<command option="no-output,no-include">
+http://%HOSTIP:%HTTPPORT/this/is/the/3008 -O --output-dir %PWD/log
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+GET /this/is/the/3008 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+</protocol>
+<file name="log/3008">
+-foo-
+</file>
+</verify>
+</testcase>
diff --git a/tests/data/test3009 b/tests/data/test3009
new file mode 100644
index 000000000..f9bf11b0e
--- /dev/null
+++ b/tests/data/test3009
@@ -0,0 +1,57 @@
+<testcase>
+<info>
+<keywords>
+-O
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+<features>
+http
+</features>
+<name>
+--output-dir a non-existing directory
+</name>
+<command option="no-output,no-include">
+http://%HOSTIP:%HTTPPORT/this/is/the/3009 -O --output-dir %PWD/not-there
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+GET /this/is/the/3009 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+</protocol>
+<errorcode>
+23
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/data/test301 b/tests/data/test301
index c40469578..760497a17 100644
--- a/tests/data/test301
+++ b/tests/data/test301
@@ -40,13 +40,11 @@ HTTPS GET with user and password
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /301 HTTP/1.1
Host: %HOSTIP:%HTTPSPORT
Authorization: Basic ZmFrZTp1c2Vy
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test3011 b/tests/data/test3011
new file mode 100644
index 000000000..267d6eeeb
--- /dev/null
+++ b/tests/data/test3011
@@ -0,0 +1,57 @@
+<testcase>
+<info>
+<keywords>
+-O
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+<features>
+http
+</features>
+<name>
+--output-dir with --create-dirs
+</name>
+<command option="no-output,no-include">
+http://%HOSTIP:%HTTPPORT/this/is/the/3011 -O --output-dir %PWD/log/tmp --create-dirs
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+GET /this/is/the/3011 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+</protocol>
+<file name="log/tmp/3011">
+-foo-
+</file>
+</verify>
+</testcase>
diff --git a/tests/data/test3012 b/tests/data/test3012
new file mode 100644
index 000000000..b4441cb18
--- /dev/null
+++ b/tests/data/test3012
@@ -0,0 +1,60 @@
+<testcase>
+<info>
+<keywords>
+-O
+-J
+--output-dir
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Content-Disposition: inline; filename="MMM3012MMM"
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+<features>
+http
+</features>
+<name>
+--output-dir with -J
+</name>
+<command option="no-output,no-include">
+http://%HOSTIP:%HTTPPORT/this/is/the/3012 -OJ --output-dir %PWD/log
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+GET /this/is/the/3012 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+</protocol>
+<file name="log/MMM3012MMM">
+-foo-
+</file>
+</verify>
+</testcase>
diff --git a/tests/data/test3013 b/tests/data/test3013
new file mode 100644
index 000000000..206b9e37a
--- /dev/null
+++ b/tests/data/test3013
@@ -0,0 +1,68 @@
+<testcase>
+<info>
+<keywords>
+-O
+-J
+--output-dir
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Content-Disposition: inline; filename="MMM3013MMM"
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+<features>
+http
+</features>
+<name>
+Two --output-dir with --next in between
+</name>
+<command option="no-output,no-include">
+http://%HOSTIP:%HTTPPORT/this/is/the/3013 -O --output-dir %PWD/log http://%HOSTIP:%HTTPPORT/another/3013 -o second3013 --output-dir %PWD/log
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+GET /this/is/the/3013 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+GET /another/3013 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+</protocol>
+<file name="log/3013">
+-foo-
+</file>
+<file2 name="log/second3013">
+-foo-
+</file2>
+</verify>
+</testcase>
diff --git a/tests/data/test3014 b/tests/data/test3014
new file mode 100644
index 000000000..e36a0e02b
--- /dev/null
+++ b/tests/data/test3014
@@ -0,0 +1,56 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+--write-out
+</keywords>
+</info>
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Content-Length: 9
+Connection: close
+Content-Type: text/plain
+
+testdata
+</data>
+
+</reply>
+
+# Client-side
+<client>
+<server>
+http
+</server>
+
+<name>
+Check if %{num_headers} returns correct number of headers
+</name>
+<command>
+http://%HOSTIP:%HTTPPORT/1439 --write-out '%{num_headers}'
+</command>
+</client>
+
+# Verify data
+<verify>
+<stdout nonewline="yes">
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Content-Length: 9
+Connection: close
+Content-Type: text/plain
+
+testdata
+4
+</stdout>
+<protocol>
+GET /1439 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test3015 b/tests/data/test3015
new file mode 100644
index 000000000..9c86d024b
--- /dev/null
+++ b/tests/data/test3015
@@ -0,0 +1,78 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+followlocation
+chunked Transfer-Encoding
+--write-out
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.1 302 OK
+Date: Sun, 13 Sep 2020 15:00 GMT
+Content-Length: 8
+Connection: close
+Content-Type: text/plain
+Location: ./30150001
+
+monster
+</data>
+<data1 nocheck="yes">
+HTTP/1.1 200 OK
+Date: Sun, 13 Sep 2020 15:00 GMT
+Transfer-Encoding: chunked
+Connection: close
+Content-Type: text/plain; charset=us-ascii
+
+0007
+bigger
+0008
+monster
+
+0
+
+</data1>
+
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+ <name>
+HTTP GET -w num_headers with redirected fetch (2 connects)
+ </name>
+ <command>
+http://%HOSTIP:%HTTPPORT/3015 -w "%{num_headers}\n" -L -o/dev/null
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+GET /3015 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+GET /30150001 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+</protocol>
+
+<stdout mode="text">
+4
+</stdout>
+
+</verify>
+</testcase>
diff --git a/tests/data/test302 b/tests/data/test302
index 3eb9e7aee..bdef98eea 100644
--- a/tests/data/test302
+++ b/tests/data/test302
@@ -43,9 +43,6 @@ HTTPS GET over HTTP proxy fails
<errorcode>
56
</errorcode>
-<strip>
-^User-Agent:.*
-</strip>
<data>
</data>
</verify>
diff --git a/tests/data/test303 b/tests/data/test303
index 01dd9ebb1..e05da5b2f 100644
--- a/tests/data/test303
+++ b/tests/data/test303
@@ -39,12 +39,10 @@ HTTPS with 8 secs timeout
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/303 HTTP/1.1
Host: %HOSTIP:%HTTPSPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test304 b/tests/data/test304
index 01d3a2d67..50baf1ca7 100644
--- a/tests/data/test304
+++ b/tests/data/test304
@@ -41,12 +41,12 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
# Verify data after the test has been "shot"
<verify>
<strip>
-^(User-Agent:|Content-Type: multipart/form-data;|------).*
+^(Content-Type: multipart/form-data;|------).*
</strip>
<protocol>
POST /we/want/304 HTTP/1.1
-User-Agent: curl/7.10.4 (i686-pc-linux-gnu) libcurl/7.10.4 OpenSSL/0.9.7a ipv6 zlib/1.1.3
Host: %HOSTIP:%HTTPSPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 1386
Content-Type: multipart/form-data; boundary=----------------------------c3b2ef7f0bb8
diff --git a/tests/data/test305 b/tests/data/test305
index 858a0040e..f60226cba 100644
--- a/tests/data/test305
+++ b/tests/data/test305
@@ -25,9 +25,6 @@ https://%HOSTIP:%HTTPSPORT/want/305 --cacert moooo
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<errorcode>
77
</errorcode>
diff --git a/tests/data/test306 b/tests/data/test306
index 17306f949..b9150af87 100644
--- a/tests/data/test306
+++ b/tests/data/test306
@@ -52,12 +52,10 @@ HTTPS GET, receive no headers only data!
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /306 HTTP/1.1
Host: %HOSTIP:%HTTPSPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test307 b/tests/data/test307
index 03c2b3c2d..5fb9faa47 100644
--- a/tests/data/test307
+++ b/tests/data/test307
@@ -43,12 +43,10 @@ simple HTTPS GET with openssl engine
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /307 HTTP/1.1
Host: %HOSTIP:%HTTPSPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test309 b/tests/data/test309
index 80246a9c0..c766fca67 100644
--- a/tests/data/test309
+++ b/tests/data/test309
@@ -65,16 +65,15 @@ HTTP Location: redirect to HTTPS URL
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/309 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /data/3090002.txt?coolsite=yes HTTP/1.1
Host: %HOSTIP:%HTTPSPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test31 b/tests/data/test31
index 633b480a9..c3b1e04ba 100644
--- a/tests/data/test31
+++ b/tests/data/test31
@@ -86,18 +86,16 @@ perl -e "print 'Test requires default test server host' if ( '%HOSTIP' ne '127.0
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/31 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
<file name="log/jar31.txt" mode="text">
# Netscape HTTP Cookie File
-# https://curl.haxx.se/docs/http-cookies.html
+# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
127.0.0.1 FALSE /we/want/ FALSE 0 prespace yes before
diff --git a/tests/data/test310 b/tests/data/test310
index e7a9379ab..128c9176d 100644
--- a/tests/data/test310
+++ b/tests/data/test310
@@ -44,12 +44,10 @@ perl -e "print 'Test requires default test server host' if ( '%HOSTIP' ne '127.0
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /310 HTTP/1.1
Host: localhost:%HTTPSPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test314 b/tests/data/test314
index f4703cdeb..899200dc1 100644
--- a/tests/data/test314
+++ b/tests/data/test314
@@ -181,15 +181,13 @@ http://%HOSTIP:%HTTPPORT/314 --compressed
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<strippart>
s/^Accept-Encoding: .*/Accept-Encoding: xxx/
</strippart>
<protocol>
GET /314 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Accept-Encoding: xxx
diff --git a/tests/data/test315 b/tests/data/test315
index c75d9ae7b..605bb0f2d 100644
--- a/tests/data/test315
+++ b/tests/data/test315
@@ -71,15 +71,13 @@ http://%HOSTIP:%HTTPPORT/315 --compressed
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<strippart>
s/^Accept-Encoding: .*/Accept-Encoding: xxx/
</strippart>
<protocol>
GET /315 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Accept-Encoding: xxx
diff --git a/tests/data/test316 b/tests/data/test316
index a293b46cd..6b95b37fd 100644
--- a/tests/data/test316
+++ b/tests/data/test316
@@ -181,15 +181,13 @@ http://%HOSTIP:%HTTPPORT/316 --compressed
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<strippart>
s/^Accept-Encoding: .*/Accept-Encoding: xxx/
</strippart>
<protocol>
GET /316 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Accept-Encoding: xxx
diff --git a/tests/data/test317 b/tests/data/test317
index 68a9b5c79..b7723c72c 100644
--- a/tests/data/test317
+++ b/tests/data/test317
@@ -75,13 +75,11 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://first.host.it.is/we/want/that/page/317 HTTP/1.1
Host: first.host.it.is
Proxy-Authorization: Basic dGVzdGluZzp0aGlz
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Authorization: s3cr3t
@@ -89,6 +87,7 @@ Authorization: s3cr3t
GET http://goto.second.host.now/3170002 HTTP/1.1
Host: goto.second.host.now
Proxy-Authorization: Basic dGVzdGluZzp0aGlz
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test318 b/tests/data/test318
index fd82c7aed..6e3621e7c 100644
--- a/tests/data/test318
+++ b/tests/data/test318
@@ -75,13 +75,11 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://first.host.it.is/we/want/that/page/318 HTTP/1.1
Host: first.host.it.is
Proxy-Authorization: Basic dGVzdGluZzp0aGlz
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Authorization: s3cr3t
@@ -89,6 +87,7 @@ Authorization: s3cr3t
GET http://goto.second.host.now/3180002 HTTP/1.1
Host: goto.second.host.now
Proxy-Authorization: Basic dGVzdGluZzp0aGlz
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Authorization: s3cr3t
diff --git a/tests/data/test319 b/tests/data/test319
index 6a61a143a..855ea3e56 100644
--- a/tests/data/test319
+++ b/tests/data/test319
@@ -44,12 +44,10 @@ http://%HOSTIP:%HTTPPORT/319 --raw
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /319 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test32 b/tests/data/test32
index 992ffcbcf..e2c5edfba 100644
--- a/tests/data/test32
+++ b/tests/data/test32
@@ -42,13 +42,10 @@ HTTP with -d and -G
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /32?foo=moo&moo=poo HTTP/1.1
-User-Agent: curl/7.9.5 (i686-pc-linux-gnu) libcurl 7.9.5-cvs (OpenSSL 0.9.5) (ipv6 enabled)
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test325 b/tests/data/test325
index 922f37ba2..93d7e21a3 100644
--- a/tests/data/test325
+++ b/tests/data/test325
@@ -49,12 +49,10 @@ HTTPS with attempted redirect to denied HTTP
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /325 HTTP/1.1
Host: %HOSTIP:%HTTPSPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test326 b/tests/data/test326
index 1a4aae5f9..09ca9c0ad 100644
--- a/tests/data/test326
+++ b/tests/data/test326
@@ -53,12 +53,10 @@ http://%HOSTIP:%HTTPPORT/326 --raw
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /326 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test327 b/tests/data/test327
index 3a1c07162..84d56f2ec 100644
--- a/tests/data/test327
+++ b/tests/data/test327
@@ -49,23 +49,22 @@ http://%HOSTIP:%HTTPPORT/we/want/327 -b none -c log/cookies327 http://%HOSTIP:%H
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/327 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /we/want/3270002 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Cookie: foobar=name
</protocol>
<file name="log/cookies327" mode="text">
# Netscape HTTP Cookie File
-# https://curl.haxx.se/docs/http-cookies.html
+# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
</file>
diff --git a/tests/data/test328 b/tests/data/test328
index 93c00e182..bc353a578 100644
--- a/tests/data/test328
+++ b/tests/data/test328
@@ -42,12 +42,12 @@ http://%HOSTIP:%HTTPPORT/hello/328 --compressed
# Verify data after the test has been "shot"
<verify>
<strip>
-^User-Agent:.*
^Accept-Encoding:.*
</strip>
<protocol>
GET /hello/328 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test329 b/tests/data/test329
index 2274d475b..e766c83ef 100644
--- a/tests/data/test329
+++ b/tests/data/test329
@@ -52,17 +52,16 @@ http://%HOSTIP:%HTTPPORT/we/want/329 -b log/jar329.txt -H "Host: host.foo.com" h
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/329 HTTP/1.1
Host: host.foo.com
+User-Agent: curl/%VERSION
Accept: */*
Cookie: test=no
GET /we/want/3290002 HTTP/1.1
Host: host.foo.com
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test33 b/tests/data/test33
index 9f7c31fb1..6b3c9d72c 100644
--- a/tests/data/test33
+++ b/tests/data/test33
@@ -42,14 +42,11 @@ http://%HOSTIP:%HTTPPORT/33 -Tlog/test33.txt -C 50
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /33 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Content-Range: bytes 50-99/100
-User-Agent: curl/7.6 (sparc-sun-solaris2.7) libcurl 7.6-pre4 (SSL 0.9.6) (krb4 enabled)
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 50
Expect: 100-continue
diff --git a/tests/data/test330 b/tests/data/test330
index 6cda172f6..40cc09740 100644
--- a/tests/data/test330
+++ b/tests/data/test330
@@ -73,18 +73,17 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://first.host.it.is/we/want/that/page/317 HTTP/1.1
Host: first.host.it.is
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Cookie: test=yes
GET http://goto.second.host.now/3170002 HTTP/1.1
Host: goto.second.host.now
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test331 b/tests/data/test331
index 2ffac81f7..f6b008543 100644
--- a/tests/data/test331
+++ b/tests/data/test331
@@ -48,17 +48,16 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://moo/we/want/331 HTTP/1.1
Host: moo
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://moo/we/want/3310002 HTTP/1.1
Host: moo
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Cookie: moo=yes
diff --git a/tests/data/test334 b/tests/data/test334
index c02a65b8d..f43af2381 100644
--- a/tests/data/test334
+++ b/tests/data/test334
@@ -31,12 +31,10 @@ http://%HOSTIP:%HTTPPORT/want/334
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/334 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test335 b/tests/data/test335
index 91d981827..e3e1950f1 100644
--- a/tests/data/test335
+++ b/tests/data/test335
@@ -73,20 +73,17 @@ http://digest:alot@data.from.server.requiring.digest.hohoho.com/335 --proxy http
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
GET http://data.from.server.requiring.digest.hohoho.com/335 HTTP/1.1
Host: data.from.server.requiring.digest.hohoho.com
-User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b zlib/1.1.4 c-ares/1.2.0 libidn/0.4.3
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://data.from.server.requiring.digest.hohoho.com/335 HTTP/1.1
Host: data.from.server.requiring.digest.hohoho.com
Proxy-Authorization: Digest username="foo", realm="weirdorealm", nonce="12345", uri="/335", response="f61609cd8f5bb205ef4e169b2c5626cb"
-User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b zlib/1.1.4 c-ares/1.2.0 libidn/0.4.3
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
@@ -94,7 +91,7 @@ GET http://data.from.server.requiring.digest.hohoho.com/335 HTTP/1.1
Host: data.from.server.requiring.digest.hohoho.com
Proxy-Authorization: Digest username="foo", realm="weirdorealm", nonce="12345", uri="/335", response="f61609cd8f5bb205ef4e169b2c5626cb"
Authorization: Digest username="digest", realm="realmweirdo", nonce="123456", uri="/335", response="08a2e2e684047f4219a38ddc189ac00c"
-User-Agent: curl/7.12.0-CVS (i686-pc-linux-gnu) libcurl/7.12.0-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4 GSS libidn/0.4.3
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test338 b/tests/data/test338
index 0c040c28a..83fe7263d 100644
--- a/tests/data/test338
+++ b/tests/data/test338
@@ -45,16 +45,15 @@ http://%HOSTIP:%HTTPPORT/338 --next http://%HOSTIP:%HTTPPORT/338 --anyauth -u fo
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /338 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /338 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
[DISCONNECT]
diff --git a/tests/data/test339 b/tests/data/test339
index cd6e49892..eca35947d 100644
--- a/tests/data/test339
+++ b/tests/data/test339
@@ -14,7 +14,7 @@ Server: fakeit/0.9 fakeitbad/1.0
Transfer-Encoding: chunked
Trailer: chunky-trailer
Connection: mooo
-ETag: "asdf"
+ETag: W/"asdf"
40
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -46,17 +46,15 @@ http://%HOSTIP:%HTTPPORT/339 --etag-save log/etag339
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /339 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
<file name="log/etag339">
-asdf
+W/"asdf"
</file>
</verify>
diff --git a/tests/data/test34 b/tests/data/test34
index a332b8c4b..fa4928d5c 100644
--- a/tests/data/test34
+++ b/tests/data/test34
@@ -52,12 +52,10 @@ http://%HOSTIP:%HTTPPORT/34
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /34 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test341 b/tests/data/test341
index 5e952ad98..726000d16 100644
--- a/tests/data/test341
+++ b/tests/data/test341
@@ -46,9 +46,6 @@ http://%HOSTIP:%HTTPPORT/341 --etag-compare log/etag341
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<errorcode>
26
</errorcode>
diff --git a/tests/data/test342 b/tests/data/test342
index 95297ba50..5a1615f1d 100644
--- a/tests/data/test342
+++ b/tests/data/test342
@@ -34,7 +34,7 @@ http
Check if --etag-compare set correct etag in header
</name>
<file name="log/etag342">
-21025-dc7-39462498
+"21025-dc7-39462498"
</file>
<command>
http://%HOSTIP:%HTTPPORT/342 --etag-compare log/etag342
@@ -44,12 +44,10 @@ http://%HOSTIP:%HTTPPORT/342 --etag-compare log/etag342
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /342 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
If-None-Match: "21025-dc7-39462498"
diff --git a/tests/data/test343 b/tests/data/test343
index e55a181d8..6e8077629 100644
--- a/tests/data/test343
+++ b/tests/data/test343
@@ -34,7 +34,7 @@ http
Both --etag-compare and --etag-save to save new Etag
</name>
<file name="log/etag343">
-21025-dc7-39462498
+"21025-dc7-39462498"
</file>
<command>
http://%HOSTIP:%HTTPPORT/343 --etag-compare log/etag343 --etag-save log/out343
@@ -44,18 +44,16 @@ http://%HOSTIP:%HTTPPORT/343 --etag-compare log/etag343 --etag-save log/out343
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /343 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
If-None-Match: "21025-dc7-39462498"
</protocol>
<file name="log/out343">
-21025-dc7-11111
+"21025-dc7-11111"
</file>
</verify>
</testcase>
diff --git a/tests/data/test344 b/tests/data/test344
index 054d0351b..5672366ec 100644
--- a/tests/data/test344
+++ b/tests/data/test344
@@ -41,18 +41,16 @@ http://%HOSTIP:%HTTPPORT/344 --etag-compare log/etag344 --etag-save log/etag344
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /344 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
If-None-Match: ""
</protocol>
<file name="log/etag344">
-21025-dc7-11111
+"21025-dc7-11111"
</file>
</verify>
</testcase>
diff --git a/tests/data/test345 b/tests/data/test345
index 135e0c26a..87687324e 100644
--- a/tests/data/test345
+++ b/tests/data/test345
@@ -34,7 +34,7 @@ http
Both --etag-compare and -save store new Etag using one pre-existing file
</name>
<file name="log/etag345">
-21025-dc7-39462498
+"21025-dc7-39462498"
</file>
<command>
http://%HOSTIP:%HTTPPORT/345 --etag-compare log/etag345 --etag-save log/etag345
@@ -44,18 +44,16 @@ http://%HOSTIP:%HTTPPORT/345 --etag-compare log/etag345 --etag-save log/etag345
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /345 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
If-None-Match: "21025-dc7-39462498"
</protocol>
<file name="log/etag345">
-21025-dc7-11111
+"21025-dc7-11111"
</file>
</verify>
</testcase>
diff --git a/tests/data/test346 b/tests/data/test346
index 64923117e..3ec7a1a9e 100644
--- a/tests/data/test346
+++ b/tests/data/test346
@@ -44,14 +44,12 @@ HTTP GET over proxy with credentials using blank passwords
#
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://remote.example/346 HTTP/1.1
Host: remote.example
Proxy-Authorization: Basic cHVzZXI6
Authorization: Basic c3VzZXI6
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test347 b/tests/data/test347
new file mode 100644
index 000000000..3d55a5bd2
--- /dev/null
+++ b/tests/data/test347
@@ -0,0 +1,60 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.1 200 funky chunky!
+Server: fakeit/0.9 fakeitbad/1.0
+Transfer-Encoding: chunked
+Trailer: chunky-trailer
+Connection: mooo
+ETag:
+
+40
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+30
+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+21;heresatest=moooo
+cccccccccccccccccccccccccccccccc
+
+0
+chunky-trailer: header data
+
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+<name>
+--etag-save with blank incoming header
+</name>
+<command>
+http://%HOSTIP:%HTTPPORT/347 --etag-save log/etag347
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+GET /347 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+</protocol>
+<file name="log/etag347">
+</file>
+</verify>
+
+</testcase>
diff --git a/tests/data/test348 b/tests/data/test348
new file mode 100644
index 000000000..befd9fb81
--- /dev/null
+++ b/tests/data/test348
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+FTP
+EPSV
+STOR
+</keywords>
+</info>
+
+<reply>
+<servercmd>
+STOR 552 disk full
+</servercmd>
+</reply>
+
+# Client-side
+<client>
+<server>
+ftp
+</server>
+ <name>
+FTP upload file with 552 disk full response
+ </name>
+<file name="log/test348.txt">
+data
+ to
+ see
+that FTP
+works
+ so does it?
+</file>
+ <command>
+ftp://%HOSTIP:%FTPPORT/348 -T log/test348.txt
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<upload>
+data
+ to
+ see
+that FTP
+works
+ so does it?
+</upload>
+<protocol>
+USER anonymous
+PASS ftp@example.com
+PWD
+EPSV
+TYPE I
+STOR 348
+QUIT
+</protocol>
+# 70 - CURLE_REMOTE_DISK_FULL
+<errorcode>
+70
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/data/test35 b/tests/data/test35
index 85733a456..5b6aba0af 100644
--- a/tests/data/test35
+++ b/tests/data/test35
Binary files differ
diff --git a/tests/data/test355 b/tests/data/test355
index e9c4cb28f..1cab2dd4a 100644
--- a/tests/data/test355
+++ b/tests/data/test355
@@ -44,12 +44,10 @@ h1 example.com 80 h1 %HOSTIP %HTTPPORT "20290222 22:19:28" 0 0
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /355 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test356 b/tests/data/test356
index c1234b450..4e4a25c17 100644
--- a/tests/data/test356
+++ b/tests/data/test356
@@ -47,12 +47,10 @@ http://%HOSTIP:%HTTPPORT/356 --alt-svc "log/altsvc-356"
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /356 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
@@ -62,7 +60,7 @@ Accept: */*
s/\"([^\"]*)\"/TIMESTAMP/
</stripfile>
<file name="log/altsvc-356" mode="text">
-# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html
+# Your alt-svc cache. https://curl.se/docs/alt-svc.html
# This file was generated by libcurl! Edit at your own risk.
h1 %HOSTIP %HTTPPORT h1 nowhere.foo 81 TIMESTAMP 0 0
</file>
diff --git a/tests/data/test357 b/tests/data/test357
index d0437c685..9e7ed86a5 100644
--- a/tests/data/test357
+++ b/tests/data/test357
@@ -68,18 +68,17 @@ the
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /we/want/357 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 78
Expect: 100-continue
PUT /we/want/357 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 78
diff --git a/tests/data/test358 b/tests/data/test358
index 82ff8adf7..6a1c9dfd2 100644
--- a/tests/data/test358
+++ b/tests/data/test358
@@ -65,7 +65,6 @@ content-length: 6
content-type: text/html
funny-head: yesyes
alt-svc: h2=":%HTTP2PORT", ma=315360000; persist=0
-server: nghttpx
via: 1.1 nghttpx
-foo-
@@ -75,18 +74,18 @@ content-length: 6
content-type: text/html
funny-head: yesyes
alt-svc: h2=":%HTTP2PORT", ma=315360000; persist=0
-server: nghttpx
via: 1.1 nghttpx
-foo-
</stdout>
<stripfile>
+s/^server: nghttpx.*\r?\n//
# strip out the (dynamic) expire date from the file so that the rest
# matches
s/\"2([^\"]*)\"/TIMESTAMP/
</stripfile>
<file name="log/altsvc-358" mode="text">
-# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html
+# Your alt-svc cache. https://curl.se/docs/alt-svc.html
# This file was generated by libcurl! Edit at your own risk.
h2 %HOSTIP %HTTPPORT h2 %HOSTIP %HTTP2PORT TIMESTAMP 0 0
</file>
diff --git a/tests/data/test359 b/tests/data/test359
index c0faee21d..84f4fcf98 100644
--- a/tests/data/test359
+++ b/tests/data/test359
@@ -65,7 +65,6 @@ content-length: 6
content-type: text/html
funny-head: yesyes
alt-svc: h2=":%HTTP2PORT", ma=315360000; persist=0
-server: nghttpx
via: 1.1 nghttpx
-foo-
@@ -75,18 +74,18 @@ content-length: 6
content-type: text/html
funny-head: yesyes
alt-svc: h2=":%HTTP2PORT", ma=315360000; persist=0
-server: nghttpx
via: 1.1 nghttpx
-foo-
</stdout>
<stripfile>
+s/^server: nghttpx.*\r?\n//
# strip out the (dynamic) expire date from the file so that the rest
# matches
s/\"2([^\"]*)\"/TIMESTAMP/
</stripfile>
<file name="log/altsvc-359" mode="text">
-# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html
+# Your alt-svc cache. https://curl.se/docs/alt-svc.html
# This file was generated by libcurl! Edit at your own risk.
h2 %HOSTIP %HTTPSPORT h2 %HOSTIP %HTTP2PORT TIMESTAMP 0 0
</file>
diff --git a/tests/data/test36 b/tests/data/test36
index 4e3fd8c87..91db26ec6 100644
--- a/tests/data/test36
+++ b/tests/data/test36
@@ -52,12 +52,10 @@ http://%HOSTIP:%HTTPPORT/36
<errorcode>
56
</errorcode>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /36 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test37 b/tests/data/test37
index 768762300..1dedfde79 100644
--- a/tests/data/test37
+++ b/tests/data/test37
@@ -33,12 +33,10 @@ http://%HOSTIP:%HTTPPORT/37
<errorcode>
52
</errorcode>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /37 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test38 b/tests/data/test38
index db257f2f8..518aae95b 100644
--- a/tests/data/test38
+++ b/tests/data/test38
@@ -41,13 +41,11 @@ download on.
<errorcode>
33
</errorcode>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/38 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Range: bytes=78-
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test39 b/tests/data/test39
index 3c6c57328..de9a51631 100644
--- a/tests/data/test39
+++ b/tests/data/test39
@@ -40,12 +40,12 @@ foo
# Verify data after the test has been "shot"
<verify>
<strip>
-^(User-Agent:|Content-Type: multipart/form-data;|-------).*
+^(Content-Type: multipart/form-data;|-------).*
</strip>
<protocol>
POST /we/want/39 HTTP/1.1
-User-Agent: curl/7.10.4 (i686-pc-linux-gnu) libcurl/7.10.4 OpenSSL/0.9.7a ipv6 zlib/1.1.3
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 1184
Content-Type: multipart/form-data; boundary=----------------------------24e78000bd32
diff --git a/tests/data/test393 b/tests/data/test393
index f03e9a246..67ce1c10f 100644
--- a/tests/data/test393
+++ b/tests/data/test393
@@ -47,12 +47,10 @@ http://%HOSTIP:%HTTPPORT/393 --max-filesize 2000000
<errorcode>
63
</errorcode>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /393 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test394 b/tests/data/test394
index b82039b4d..ec7a06d92 100644
--- a/tests/data/test394
+++ b/tests/data/test394
@@ -46,12 +46,10 @@ http://%HOSTIP:%HTTPPORT/394
<errorcode>
8
</errorcode>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /394 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test395 b/tests/data/test395
index 2a569bf3b..fae55dbf0 100644
--- a/tests/data/test395
+++ b/tests/data/test395
@@ -42,12 +42,10 @@ http://%HOSTIP:%HTTPPORT/395
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /395 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test396 b/tests/data/test396
index 1dd03421f..01be58ac3 100644
--- a/tests/data/test396
+++ b/tests/data/test396
@@ -185,15 +185,13 @@ http://%HOSTIP:%HTTPPORT/396 --compressed
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<strippart>
s/^Accept-Encoding: .*/Accept-Encoding: xxx/
</strippart>
<protocol>
GET /396 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Accept-Encoding: xxx
diff --git a/tests/data/test397 b/tests/data/test397
index 6f872e2ac..0afd21c60 100644
--- a/tests/data/test397
+++ b/tests/data/test397
@@ -181,15 +181,13 @@ http://%HOSTIP:%HTTPPORT/397 --compressed
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<strippart>
s/^Accept-Encoding: .*/Accept-Encoding: xxx/
</strippart>
<protocol>
GET /397 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Accept-Encoding: xxx
diff --git a/tests/data/test4 b/tests/data/test4
index 542347db5..fe5789ad6 100644
--- a/tests/data/test4
+++ b/tests/data/test4
@@ -37,12 +37,10 @@ Replaced internal and added custom HTTP headers
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /4 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
extra-header: here
Accept: replaced
X-Custom-Header:
@@ -51,6 +49,7 @@ X-Test2: foo;
GET /4 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
extra-header: here
Accept: replaced
X-Custom-Header:
diff --git a/tests/data/test40 b/tests/data/test40
index 6be0d1615..42bd8e13b 100644
--- a/tests/data/test40
+++ b/tests/data/test40
@@ -56,17 +56,15 @@ http://%HOSTIP:%HTTPPORT/we/are/all/twits/40 -L
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/are/all/twits/40 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /we/are/all/moo.html/?name=d+a+niel&testcase=/400002 HTTP/1.1
-User-Agent: curl/7.10 (i686-pc-linux-gnu) libcurl/7.10 OpenSSL/0.9.6c ipv6 zlib/1.1.3
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test42 b/tests/data/test42
index e303f3a27..abb3412ee 100644
--- a/tests/data/test42
+++ b/tests/data/test42
@@ -56,17 +56,15 @@ http://%HOSTIP:%HTTPPORT/we/are/all/twits/42 -L
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/are/all/twits/42 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /we/are/all/m%20o%20o.html/420002 HTTP/1.1
-User-Agent: curl/7.10 (i686-pc-linux-gnu) libcurl/7.10 OpenSSL/0.9.6c ipv6 zlib/1.1.3
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test43 b/tests/data/test43
index 196017013..28035c899 100644
--- a/tests/data/test43
+++ b/tests/data/test43
@@ -63,17 +63,16 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://%HOSTIP:%HTTPPORT/want/43 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://%HOSTIP:%HTTPPORT/want/data/430002.txt?coolsite=yes HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test430 b/tests/data/test430
index d4dc530dd..4a669ff7e 100644
--- a/tests/data/test430
+++ b/tests/data/test430
@@ -70,12 +70,10 @@ Three -K uses with --next and --data in each
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /4300001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
a: a
Content-Length: 1
@@ -83,6 +81,7 @@ Content-Type: application/x-www-form-urlencoded
aPOST /4300002 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
b: b
Content-Length: 1
@@ -90,6 +89,7 @@ Content-Type: application/x-www-form-urlencoded
bPOST /4300003 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
c: c
Content-Length: 1
diff --git a/tests/data/test431 b/tests/data/test431
index 48a1b20a1..8f045482b 100644
--- a/tests/data/test431
+++ b/tests/data/test431
@@ -64,12 +64,10 @@ Two -K uses with --next and then one on cmdline
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /4310001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
a: a
Content-Length: 1
@@ -77,6 +75,7 @@ Content-Type: application/x-www-form-urlencoded
aPOST /4310002 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
b: b
Content-Length: 1
@@ -84,6 +83,7 @@ Content-Type: application/x-www-form-urlencoded
bPOST /4310003 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
c: c
Content-Length: 1
diff --git a/tests/data/test432 b/tests/data/test432
index b3401b687..a7bc37886 100644
--- a/tests/data/test432
+++ b/tests/data/test432
@@ -69,12 +69,10 @@ Use -K with --next and --config from within
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /4320001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
a: a
Content-Length: 1
@@ -82,6 +80,7 @@ Content-Type: application/x-www-form-urlencoded
aPOST /4320002 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
b: b
Content-Length: 1
@@ -89,6 +88,7 @@ Content-Type: application/x-www-form-urlencoded
bPOST /4320003 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
c: c
Content-Length: 1
diff --git a/tests/data/test433 b/tests/data/test433
new file mode 100644
index 000000000..e7cb4d225
--- /dev/null
+++ b/tests/data/test433
@@ -0,0 +1,57 @@
+<testcase>
+<info>
+<keywords>
+--config
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+HTTP/1.1 200 OK
+Content-Length: 6
+Content-Type: text/1
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<file1 name="log/.curlrc">
+--next
+header = "a: a"
+data = "curlrc read"
+</file1>
+<server>
+http
+</server>
+<setenv>
+XDG_CONFIG_HOME=%PWD/log
+</setenv>
+<name>
+Verify XDG_CONFIG_HOME use to find .curlrc
+</name>
+<command>
+%HOSTIP:%HTTPPORT/433
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol nonewline="yes">
+POST /433 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+a: a
+Content-Length: 11
+Content-Type: application/x-www-form-urlencoded
+
+curlrc read
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test434 b/tests/data/test434
new file mode 100644
index 000000000..a2bcc0cbd
--- /dev/null
+++ b/tests/data/test434
@@ -0,0 +1,46 @@
+<testcase>
+
+<info>
+<keywords>
+--config
+</keywords>
+</info>
+
+#
+<reply>
+<data>
+HTTP/1.1 200 OK
+Content-Length: 6
+Content-Type: text/1
+
+-foo-
+</data>
+</reply>
+
+#
+<client>
+<file name="log/config434" nonewline="yes">
+url = %HOSTIP:%HTTPPORT/434
+</file>
+<server>
+http
+</server>
+<name>
+-K with a single line without newline
+</name>
+<command>
+-K log/config434
+</command>
+</client>
+
+#
+<verify>
+<protocol>
+GET /434 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test44 b/tests/data/test44
index 8220a1aa1..4b1fa450b 100644
--- a/tests/data/test44
+++ b/tests/data/test44
@@ -40,12 +40,12 @@ bar
# Verify data after the test has been "shot"
<verify>
<strip>
-^(User-Agent:|Content-Type: multipart/form-data;|------).*
+^(Content-Type: multipart/form-data;|------).*
</strip>
<protocol>
POST /we/want/44 HTTP/1.1
-User-Agent: curl/7.10.4 (i686-pc-linux-gnu) libcurl/7.10.4 OpenSSL/0.9.7a ipv6 zlib/1.1.3
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 408
Content-Type: multipart/form-data; boundary=----------------------------7c633d5c27ce
diff --git a/tests/data/test45 b/tests/data/test45
index 3eb9ba943..1381920d9 100644
--- a/tests/data/test45
+++ b/tests/data/test45
@@ -59,16 +59,15 @@ simple HTTP Location: without protocol in initial URL
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/45 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /want/data.cgi?moo=http://&/450002 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test46 b/tests/data/test46
index 4ea259255..fb4071cf3 100644
--- a/tests/data/test46
+++ b/tests/data/test46
@@ -46,7 +46,7 @@ domain..tld:%HTTPPORT/want/46 --resolve domain..tld:%HTTPPORT:%HOSTIP -c log/jar
</command>
<file name="log/injar46">
# Netscape HTTP Cookie File
-# https://curl.haxx.se/docs/http-cookies.html
+# https://curl.se/docs/http-cookies.html
# This is generated by libcurl! Do not edit.
www.fake.come FALSE / FALSE 2147483647 cookiecliente si
@@ -59,19 +59,17 @@ domain..tld FALSE /want FALSE 0 empty
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/46 HTTP/1.1
Host: domain..tld:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Cookie: empty=; mooo2=indeed2; mooo=indeed
</protocol>
<file name="log/jar46" mode="text">
# Netscape HTTP Cookie File
-# https://curl.haxx.se/docs/http-cookies.html
+# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
domain..tld FALSE /want/ FALSE 0 simplyhuge zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
diff --git a/tests/data/test47 b/tests/data/test47
index bd779d346..2048f5229 100644
--- a/tests/data/test47
+++ b/tests/data/test47
@@ -35,12 +35,10 @@ http://%HOSTIP:%HTTPPORT/47 -0
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /47 HTTP/1.0
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test48 b/tests/data/test48
index 7ee05ad37..36bf65668 100644
--- a/tests/data/test48
+++ b/tests/data/test48
@@ -36,16 +36,15 @@ HTTP with -d and -G and -I
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
HEAD /48?foo=moo&moo=poo HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
HEAD /48?foo=moo&moo=poo HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
[DISCONNECT]
diff --git a/tests/data/test49 b/tests/data/test49
index 4a4175e32..9192f92a1 100644
--- a/tests/data/test49
+++ b/tests/data/test49
@@ -56,17 +56,15 @@ http://%HOSTIP:%HTTPPORT/we/are/all/twits/49 -L
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/are/all/twits/49 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /we/are/all/moo.html/490002 HTTP/1.1
-User-Agent: curl/7.10 (i686-pc-linux-gnu) libcurl/7.10 OpenSSL/0.9.6c ipv6 zlib/1.1.3
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test490 b/tests/data/test490
index 86ebb0112..6f77b7111 100644
--- a/tests/data/test490
+++ b/tests/data/test490
@@ -45,12 +45,10 @@ surprise!
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /490 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 10
Expect: 100-continue
@@ -58,6 +56,7 @@ Expect: 100-continue
surprise!
PUT /490 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 10
Expect: 100-continue
diff --git a/tests/data/test491 b/tests/data/test491
index c230dfb78..87cebf1ab 100644
--- a/tests/data/test491
+++ b/tests/data/test491
@@ -45,12 +45,10 @@ surprise!
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /491 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 10
Expect: 100-continue
diff --git a/tests/data/test492 b/tests/data/test492
index ddb0405ef..ab3c01fc2 100644
--- a/tests/data/test492
+++ b/tests/data/test492
@@ -48,12 +48,10 @@ second 492 contents
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /one/first492 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Testno: 492
Content-Length: 19
@@ -62,6 +60,7 @@ Expect: 100-continue
first 492 contents
PUT /two/first492 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Testno: 492
Content-Length: 19
@@ -70,6 +69,7 @@ Expect: 100-continue
first 492 contents
PUT /one/second492 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Testno: 492
Content-Length: 20
@@ -78,6 +78,7 @@ Expect: 100-continue
second 492 contents
PUT /two/second492 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Testno: 492
Content-Length: 20
diff --git a/tests/data/test493 b/tests/data/test493
new file mode 100644
index 000000000..f7758da34
--- /dev/null
+++ b/tests/data/test493
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HSTS
+url_effective
+</keywords>
+</info>
+
+<reply>
+
+# we use this as response to a CONNECT
+<data nocheck="yes">
+HTTP/1.1 403 not OK at all
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 6
+Connection: close
+Funny-head: yesyes
+
+-foo-
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<features>
+HSTS
+</features>
+
+<file name="log/input493">
+.hsts.example "20311001 04:47:41"
+</file>
+
+<name>
+HSTS and %{url_effective} after upgrade
+</name>
+<command>
+-x http://%HOSTIP:%HTTPPORT http://this.hsts.example/493 --hsts log/input493 -w '%{url_effective}\n'
+</command>
+</client>
+
+<verify>
+# we let it CONNECT to the server to confirm HSTS but deny from there
+<protocol>
+CONNECT this.hsts.example:443 HTTP/1.1
+Host: this.hsts.example:443
+User-Agent: curl/%VERSION
+Proxy-Connection: Keep-Alive
+
+</protocol>
+<stdout>
+https://this.hsts.example/493
+</stdout>
+# Proxy CONNECT aborted
+<errorcode>
+56
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/data/test5 b/tests/data/test5
index b98d27b3b..613882026 100644
--- a/tests/data/test5
+++ b/tests/data/test5
@@ -39,12 +39,10 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://%HOSTIP:%HTTPPORT/we/want/that/page/5 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test50 b/tests/data/test50
index 84b05da7b..777caa259 100644
--- a/tests/data/test50
+++ b/tests/data/test50
@@ -56,17 +56,15 @@ http://%HOSTIP:%HTTPPORT/we/are/all/twits/50 -L
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/are/all/twits/50 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /we/are/moo.html/500002 HTTP/1.1
-User-Agent: curl/7.10 (i686-pc-linux-gnu) libcurl/7.10 OpenSSL/0.9.6c ipv6 zlib/1.1.3
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test506 b/tests/data/test506
index f821ad10e..35746bb6e 100644
--- a/tests/data/test506
+++ b/tests/data/test506
@@ -55,10 +55,11 @@ run 3: overwrite cookie 1 and 4, set cookie 6 with and without tailmatch
<server>
http
</server>
-# don't run this with the threaded-resolver since the events might trigger in
-# a different order!
+# don't run this with the threaded-resolver or c-ares since the events might
+# trigger in a different order!
<features>
!threaded-resolver
+!c-ares
</features>
<name>
HTTP with shared cookie list (and dns cache)
@@ -234,7 +235,7 @@ GLOBAL_CLEANUP
</stdout>
<file name="log/jar506" mode="text">
# Netscape HTTP Cookie File
-# https://curl.haxx.se/docs/http-cookies.html
+# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
www.host.foo.com FALSE / FALSE 1993463787 test6 six_more
diff --git a/tests/data/test51 b/tests/data/test51
index b58c3570e..7d9740ae9 100644
--- a/tests/data/test51
+++ b/tests/data/test51
@@ -56,17 +56,15 @@ http://%HOSTIP:%HTTPPORT/we/are/all/twits/51 -L
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/are/all/twits/51 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /510002 HTTP/1.1
-User-Agent: curl/7.10 (i686-pc-linux-gnu) libcurl/7.10 OpenSSL/0.9.6c ipv6 zlib/1.1.3
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test511 b/tests/data/test511
index 72b79938c..1a251fd89 100644
--- a/tests/data/test511
+++ b/tests/data/test511
@@ -35,9 +35,9 @@ ftp://%HOSTIP:%FTPPORT/511
#
# Verify data after the test has been "shot"
<verify>
-# CURLE_FTP_COULDNT_RETR_FILE
+# CURLE_REMOTE_FILE_NOT_FOUND
<errorcode>
-19
+78
</errorcode>
<protocol>
USER anonymous
diff --git a/tests/data/test512 b/tests/data/test512
index d259f40df..dd5cc0a07 100644
--- a/tests/data/test512
+++ b/tests/data/test512
@@ -40,9 +40,6 @@ http://%HOSTIP:%HTTPPORT/512
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /512 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test514 b/tests/data/test514
index ca37a5d65..82f8041fd 100644
--- a/tests/data/test514
+++ b/tests/data/test514
@@ -44,9 +44,6 @@ http://%HOSTIP:%HTTPPORT/514
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
HEAD /514 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test515 b/tests/data/test515
index 526f1e136..bea2fe6f9 100644
--- a/tests/data/test515
+++ b/tests/data/test515
@@ -39,9 +39,6 @@ http://%HOSTIP:%HTTPPORT/515
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
POST /515 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test516 b/tests/data/test516
index 9bc175bd4..c41d15e7e 100644
--- a/tests/data/test516
+++ b/tests/data/test516
@@ -40,9 +40,6 @@ http://%HOSTIP:%HTTPPORT/516
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
POST /516 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test52 b/tests/data/test52
index 14fa42bfd..196ff041c 100644
--- a/tests/data/test52
+++ b/tests/data/test52
@@ -56,17 +56,15 @@ http://%HOSTIP:%HTTPPORT/we/are/all/twits/52 -L
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/are/all/twits/52 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /we/are/all/twits/520002 HTTP/1.1
-User-Agent: curl/7.10 (i686-pc-linux-gnu) libcurl/7.10 OpenSSL/0.9.6c ipv6 zlib/1.1.3
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test522 b/tests/data/test522
index 89a0dbf51..8fc07c390 100644
--- a/tests/data/test522
+++ b/tests/data/test522
@@ -43,9 +43,6 @@ http://%HOSTIP/522 %HTTPPORT
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /522 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test523 b/tests/data/test523
index c00a0969d..03d456b05 100644
--- a/tests/data/test523
+++ b/tests/data/test523
@@ -49,9 +49,6 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://www.example.com:19999/523 HTTP/1.1
Host: www.example.com:19999
diff --git a/tests/data/test53 b/tests/data/test53
index 679a4fa84..bffd063e5 100644
--- a/tests/data/test53
+++ b/tests/data/test53
@@ -40,12 +40,10 @@ HTTP, junk session cookies
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/53 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Cookie: mooo=indeed
diff --git a/tests/data/test530 b/tests/data/test530
deleted file mode 100644
index 40182e299..000000000
--- a/tests/data/test530
+++ /dev/null
@@ -1,83 +0,0 @@
-<testcase>
-<info>
-<keywords>
-HTTP
-pipelining
-multi
-</keywords>
-</info>
-
-# Server-side
-<reply>
-<data1>
-HTTP/1.1 200 OK
-Date: Thu, 09 Nov 2010 14:49:00 GMT
-Server: test-server/fake
-Content-Length: 47
-
-file contents should appear once for each file
-</data1>
-<data2>
-HTTP/1.1 200 OK
-</data2>
-<data3>
-Date: Thu, 09 Nov 2010 14:49:00 GMT
-</data3>
-<data4>
-Server: test-server/fake
-Content-Length: 47
-
-file contents should appear once for each file
-HTTP/1.1 200 OK
-Date: Thu, 09 Nov 2010 14:49:00 GMT
-Server: test-server/fake
-Content-Length: 47
-
-file contents should appear once for each file
-HTTP/1.1 200 OK
-Date: Thu, 09 Nov 2010 14:49:00 GMT
-Server: test-server/fake
-Content-Length: 47
-
-file contents should appear once for each file
-</data4>
-</reply>
-
-# Client-side
-<client>
-<server>
-http
-</server>
-<tool>
-lib530
-</tool>
- <name>
-HTTP GET using pipelining
- </name>
- <command>
-http://%HOSTIP:%HTTPPORT/path/530
-</command>
-</client>
-
-# Verify data after the test has been "shot"
-<verify>
-<protocol>
-GET /path/5300001 HTTP/1.1
-Host: %HOSTIP:%HTTPPORT
-Accept: */*
-
-GET /path/5300002 HTTP/1.1
-Host: %HOSTIP:%HTTPPORT
-Accept: */*
-
-GET /path/5300003 HTTP/1.1
-Host: %HOSTIP:%HTTPPORT
-Accept: */*
-
-GET /path/5300004 HTTP/1.1
-Host: %HOSTIP:%HTTPPORT
-Accept: */*
-
-</protocol>
-</verify>
-</testcase>
diff --git a/tests/data/test533 b/tests/data/test533
index f4446cbe0..a67c8c824 100644
--- a/tests/data/test533
+++ b/tests/data/test533
@@ -15,7 +15,7 @@ multi
<servercmd>
REPLY RETR 550 the file doesn't exist
-REPLY SIZE 550 Can't check for file existence
+REPLY SIZE 500 Can't check for file existence
</servercmd>
</reply>
diff --git a/tests/data/test534 b/tests/data/test534
index 6045dba61..ba3f721e7 100644
--- a/tests/data/test534
+++ b/tests/data/test534
@@ -16,7 +16,7 @@ non-existing host
<servercmd>
REPLY RETR 550 the file doesn't exist
-REPLY SIZE 550 Can't check for file existence
+REPLY SIZE 500 Can't check for file existence
</servercmd>
</reply>
diff --git a/tests/data/test54 b/tests/data/test54
index 66dbe9ddb..24f081954 100644
--- a/tests/data/test54
+++ b/tests/data/test54
@@ -32,12 +32,10 @@ http://%HOSTIP:%HTTPPORT/want/54 -L
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/54 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test540 b/tests/data/test540
index 871c558fb..8f53b072c 100644
--- a/tests/data/test540
+++ b/tests/data/test540
@@ -79,9 +79,6 @@ http://test.remote.example.com/path/540 http://%HOSTIP:%HTTPPORT silly:person cu
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
GET http://test.remote.example.com/path/540 HTTP/1.1
Host: custom.set.host.name
diff --git a/tests/data/test544 b/tests/data/test544
index 78cb5a45e..4bf9a6cbb 100644
--- a/tests/data/test544
+++ b/tests/data/test544
@@ -40,9 +40,6 @@ http://%HOSTIP:%HTTPPORT/544
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /544 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test546 b/tests/data/test546
index 12e604a0e..00dca99fa 100644
--- a/tests/data/test546
+++ b/tests/data/test546
@@ -21,7 +21,7 @@ works
<servercmd>
REPLY RETR 550 the file doesn't exist
COUNT RETR 1
-REPLY SIZE 550 Can't check for file existence
+REPLY SIZE 500 Can't check for file existence
COUNT SIZE 1
</servercmd>
</reply>
diff --git a/tests/data/test547 b/tests/data/test547
index e4ec39893..5401e06c8 100644
--- a/tests/data/test547
+++ b/tests/data/test547
@@ -100,13 +100,9 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
POST http://test.remote.example.com/path/547 HTTP/1.1
Host: test.remote.example.com
-User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 36
@@ -116,7 +112,6 @@ this is the blurb we want to upload
POST http://test.remote.example.com/path/547 HTTP/1.1
Host: test.remote.example.com
Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 0
@@ -125,7 +120,6 @@ Content-Type: application/x-www-form-urlencoded
POST http://test.remote.example.com/path/547 HTTP/1.1
Host: test.remote.example.com
Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAADj3hs3u3j0kgJqCrLM+74BmaoNHDfIJjHRlc3R1c2VyY3VybGhvc3Q=
-User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 36
diff --git a/tests/data/test548 b/tests/data/test548
index d636ab1b6..3ce5ae1ea 100644
--- a/tests/data/test548
+++ b/tests/data/test548
@@ -100,13 +100,9 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
POST http://test.remote.example.com/path/548 HTTP/1.1
Host: test.remote.example.com
-User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 36
@@ -116,7 +112,6 @@ this is the blurb we want to upload
POST http://test.remote.example.com/path/548 HTTP/1.1
Host: test.remote.example.com
Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 0
@@ -125,7 +120,6 @@ Content-Type: application/x-www-form-urlencoded
POST http://test.remote.example.com/path/548 HTTP/1.1
Host: test.remote.example.com
Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAADj3hs3u3j0kgJqCrLM+74BmaoNHDfIJjHRlc3R1c2VyY3VybGhvc3Q=
-User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 36
diff --git a/tests/data/test549 b/tests/data/test549
index a9f1ca21c..93c442aae 100644
--- a/tests/data/test549
+++ b/tests/data/test549
@@ -49,9 +49,6 @@ ftp://www.example.com/moo/549 http://%HOSTIP:%HTTPPORT
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET ftp://www.example.com/moo/549;type=i HTTP/1.1
Host: www.example.com:21
diff --git a/tests/data/test55 b/tests/data/test55
index 662385608..216f13cef 100644
--- a/tests/data/test55
+++ b/tests/data/test55
@@ -48,17 +48,15 @@ http://%HOSTIP:%HTTPPORT/55 -L
</client>
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /55 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /550002 HTTP/1.1
-User-Agent: curl/7.10 (i686-pc-linux-gnu) libcurl/7.10 OpenSSL/0.9.6c ipv6 zlib/1.1.3
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test550 b/tests/data/test550
index 1eff72a17..bd8f4223e 100644
--- a/tests/data/test550
+++ b/tests/data/test550
@@ -49,9 +49,6 @@ ftp://www.example.com/moo/550 http://%HOSTIP:%HTTPPORT ascii
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET ftp://www.example.com/moo/550;type=a HTTP/1.1
Host: www.example.com:21
diff --git a/tests/data/test551 b/tests/data/test551
index bb31a36f8..30c0ed940 100644
--- a/tests/data/test551
+++ b/tests/data/test551
@@ -75,9 +75,6 @@ http://test.remote.example.com/path/551 http://%HOSTIP:%HTTPPORT s1lly:pers0n
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
POST http://test.remote.example.com/path/551 HTTP/1.1
Host: test.remote.example.com
diff --git a/tests/data/test552 b/tests/data/test552
index a02023a59..9ad37bd7e 100644
--- a/tests/data/test552
+++ b/tests/data/test552
Binary files differ
diff --git a/tests/data/test553 b/tests/data/test553
index bd937f016..3ddb53295 100644
--- a/tests/data/test553
+++ b/tests/data/test553
@@ -41,25 +41,22 @@ http://%HOSTIP:%HTTPPORT/path/553
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol nonewline="yes">
POST /path/553 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Accept: */*
-Header0: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-Header1: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-Header2: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-Header3: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-Header4: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-Header5: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-Header6: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-Header7: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+Header0: %repeat[5000 x A]%
+Header1: %repeat[5000 x A]%
+Header2: %repeat[5000 x A]%
+Header3: %repeat[5000 x A]%
+Header4: %repeat[5000 x A]%
+Header5: %repeat[5000 x A]%
+Header6: %repeat[5000 x A]%
+Header7: %repeat[5000 x A]%
Content-Length: 40960
Content-Type: application/x-www-form-urlencoded
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+%repeat[40960 x A]%
</protocol>
</verify>
</testcase>
diff --git a/tests/data/test555 b/tests/data/test555
index ed8117f8f..506cbb4a0 100644
--- a/tests/data/test555
+++ b/tests/data/test555
@@ -105,13 +105,9 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
<protocol>
POST http://test.remote.example.com/path/555 HTTP/1.1
Host: test.remote.example.com
-User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 36
@@ -121,7 +117,6 @@ this is the blurb we want to upload
POST http://test.remote.example.com/path/555 HTTP/1.1
Host: test.remote.example.com
Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 0
@@ -130,7 +125,6 @@ Content-Type: application/x-www-form-urlencoded
POST http://test.remote.example.com/path/555 HTTP/1.1
Host: test.remote.example.com
Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAADj3hs3u3j0kgJqCrLM+74BmaoNHDfIJjHRlc3R1c2VyY3VybGhvc3Q=
-User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 36
diff --git a/tests/data/test556 b/tests/data/test556
index 549b9a4a2..72a8b9e47 100644
--- a/tests/data/test556
+++ b/tests/data/test556
@@ -38,9 +38,6 @@ http://%HOSTIP:%HTTPPORT
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /556 HTTP/1.2
Host: ninja
diff --git a/tests/data/test558 b/tests/data/test558
index d5aa0e087..f313e813a 100644
--- a/tests/data/test558
+++ b/tests/data/test558
@@ -38,8 +38,8 @@ nothing
<file name="log/memdump">
MEM lib558.c: malloc()
MEM lib558.c: free()
-MEM strdup.c: realloc()
-MEM strdup.c: realloc()
+MEM dynbuf.c: realloc()
+MEM dynbuf.c: realloc()
MEM escape.c: free()
</file>
<stripfile>
diff --git a/tests/data/test56 b/tests/data/test56
index f221981c4..394ac3574 100644
--- a/tests/data/test56
+++ b/tests/data/test56
@@ -34,7 +34,7 @@ data "we post this"
header "Transfer-Encoding: chunked"
#
# Set the user-agent using a short-option:
--A "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+-A "%repeat[99999 x a]%"
#
</stdin>
<command>
@@ -47,7 +47,7 @@ header "Transfer-Encoding: chunked"
<protocol>
POST /that.site.com/56 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
-User-Agent: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+User-Agent: %repeat[99999 x a]%
Accept: */*
Transfer-Encoding: chunked
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test560 b/tests/data/test560
index 8d005541f..72a35e4b8 100644
--- a/tests/data/test560
+++ b/tests/data/test560
@@ -43,9 +43,6 @@ https://%HOSTIP:%HTTPSPORT/560
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /560 HTTP/1.1
Host: %HOSTIP:%HTTPSPORT
diff --git a/tests/data/test561 b/tests/data/test561
index 359e54cca..2f244617c 100644
--- a/tests/data/test561
+++ b/tests/data/test561
@@ -50,9 +50,6 @@ FTP RETR with CURLOPT_PROXY_TRANSFER_MODE, ASCII transfer and type=i
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET ftp://www.example.com/moo/561;type=i HTTP/1.1
Host: www.example.com:21
diff --git a/tests/data/test57 b/tests/data/test57
index 0724eac82..5011e6eb0 100644
--- a/tests/data/test57
+++ b/tests/data/test57
@@ -35,12 +35,10 @@ HTTP content-type with spaces in
<stdout mode="text">
text/html; charset=ISO-8859-4
</stdout>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /57 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test573 b/tests/data/test573
index e3299b820..b76f259c9 100644
--- a/tests/data/test573
+++ b/tests/data/test573
@@ -45,9 +45,6 @@ http://%HOSTIP:%HTTPPORT/573
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /573 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test58 b/tests/data/test58
index 1bd53fa27..f2eafe23a 100644
--- a/tests/data/test58
+++ b/tests/data/test58
@@ -35,12 +35,10 @@ a few bytes
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /we/want/58te%5B%5Dst.txt HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 12
Expect: 100-continue
diff --git a/tests/data/test580 b/tests/data/test580
index 13965598f..b448ee337 100644
--- a/tests/data/test580
+++ b/tests/data/test580
@@ -45,9 +45,6 @@ http://%HOSTIP:%HTTPPORT/580
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /580 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test581 b/tests/data/test581
index 83d7b604e..92871c3e6 100644
--- a/tests/data/test581
+++ b/tests/data/test581
@@ -45,9 +45,6 @@ http://%HOSTIP:%HTTPPORT/581
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /581 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test584 b/tests/data/test584
deleted file mode 100644
index 309c7b65b..000000000
--- a/tests/data/test584
+++ /dev/null
@@ -1,102 +0,0 @@
-<testcase>
-<info>
-<keywords>
-HTTP
-pipelining
-multi
-</keywords>
-</info>
-
-# Server-side
-# Silly division of the first request is solely to appease the server which expects n_data_items == n_requests
-<reply>
-<data1>
-HTTP/1.1 200 OK
-Server: test-server/fake
-Content-Length: 4
-
-584
-</data1>
-<data2>
-HTTP/1.1 200 OK
-</data2>
-<data3>
-Server: test-server/fake
-</data3>
-<data4>
-Content-Length: 0
-
-HTTP/1.1 200 OK
-Server: test-server/fake
-Content-Length: 5
-
-585
-
-HTTP/1.1 200 OK
-Server: test-server/fake
-Content-Length: 4
-
-586
-</data4>
-</reply>
-
-# Client-side
-<client>
-<server>
-http
-</server>
-<tool>
-lib530
-</tool>
- <name>
-HTTP GET using pipelining (nonzero length after zero length)
- </name>
- <command>
-http://%HOSTIP:%HTTPPORT/path/584
-</command>
-</client>
-
-# Verify data after the test has been "shot"
-<verify>
-<protocol>
-GET /path/5840001 HTTP/1.1
-Host: %HOSTIP:%HTTPPORT
-Accept: */*
-
-GET /path/5840002 HTTP/1.1
-Host: %HOSTIP:%HTTPPORT
-Accept: */*
-
-GET /path/5840003 HTTP/1.1
-Host: %HOSTIP:%HTTPPORT
-Accept: */*
-
-GET /path/5840004 HTTP/1.1
-Host: %HOSTIP:%HTTPPORT
-Accept: */*
-
-</protocol>
-<stdout>
-HTTP/1.1 200 OK
-Server: test-server/fake
-Content-Length: 4
-
-584
-HTTP/1.1 200 OK
-Server: test-server/fake
-Content-Length: 0
-
-HTTP/1.1 200 OK
-Server: test-server/fake
-Content-Length: 5
-
-585
-
-HTTP/1.1 200 OK
-Server: test-server/fake
-Content-Length: 4
-
-586
-</stdout>
-</verify>
-</testcase>
diff --git a/tests/data/test585 b/tests/data/test585
index 2096e81c3..ecde4beb0 100644
--- a/tests/data/test585
+++ b/tests/data/test585
@@ -56,9 +56,6 @@ http://%HOSTIP:%HTTPPORT/585
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /585 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test589 b/tests/data/test589
index 451bb15bd..81f788100 100644
--- a/tests/data/test589
+++ b/tests/data/test589
@@ -41,9 +41,6 @@ http://%HOSTIP:%HTTPPORT/589
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
POST /589 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test59 b/tests/data/test59
index 9c9601778..b93f99d6c 100644
--- a/tests/data/test59
+++ b/tests/data/test59
@@ -34,12 +34,10 @@ HTTP URL with slash but with "parameter"
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /?mooo/59 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test590 b/tests/data/test590
index 5ddc823a5..cb24cbb56 100644
--- a/tests/data/test590
+++ b/tests/data/test590
@@ -98,27 +98,22 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent: curl/.*
-</strip>
+
<protocol>
GET http://test.remote.example.com/path/590 HTTP/1.1
Host: test.remote.example.com
-User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
Accept: */*
Proxy-Connection: Keep-Alive
GET http://test.remote.example.com/path/590 HTTP/1.1
Host: test.remote.example.com
Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
Accept: */*
Proxy-Connection: Keep-Alive
GET http://test.remote.example.com/path/590 HTTP/1.1
Host: test.remote.example.com
Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAAAgACAHAAAAAIAAgAcgAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAAIWYOdZV0iKA8ytf+dU+Bz9TpMJ4mBKu221lY3VybGhvc3Q=
-User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test6 b/tests/data/test6
index 0e7dc9b24..09664cdbb 100644
--- a/tests/data/test6
+++ b/tests/data/test6
@@ -35,12 +35,10 @@ http://%HOSTIP:%HTTPPORT/we/want/that/page/6 -b "name=contents;name2=content2"
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/that/page/6 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Cookie: name=contents;name2=content2
diff --git a/tests/data/test60 b/tests/data/test60
index 0dd717f8d..09cd54f83 100644
--- a/tests/data/test60
+++ b/tests/data/test60
@@ -37,12 +37,10 @@ more than one byte
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /bzz/60 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Transfer-Encoding: chunked
Content-Length: 1
diff --git a/tests/data/test61 b/tests/data/test61
index 2bf6490f7..1ccdffc53 100644
--- a/tests/data/test61
+++ b/tests/data/test61
@@ -51,18 +51,16 @@ http://%HOSTIP:%HTTPPORT/we/want/61 -c log/jar61.txt -H "Host: www.host.foo.com"
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/61 HTTP/1.1
Host: www.host.foo.com
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
<file name="log/jar61.txt" mode="text">
# Netscape HTTP Cookie File
-# https://curl.haxx.se/docs/http-cookies.html
+# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
.host.foo.com TRUE /we/want/ FALSE 2118138987 test2 yes
diff --git a/tests/data/test62 b/tests/data/test62
index 82bc0d783..18d516892 100644
--- a/tests/data/test62
+++ b/tests/data/test62
@@ -33,7 +33,7 @@ http://%HOSTIP:%HTTPPORT/we/want/62 http://%HOSTIP:%HTTPPORT/we/want/62?hoge=fug
</command>
<file name="log/jar62.txt">
# Netscape HTTP Cookie File
-# https://curl.haxx.se/docs/http-cookies.html
+# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
#HttpOnly_.foo.com TRUE /we/want/ FALSE 2147483647 test yes
@@ -46,17 +46,16 @@ http://%HOSTIP:%HTTPPORT/we/want/62 http://%HOSTIP:%HTTPPORT/we/want/62?hoge=fug
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/62 HTTP/1.1
Host: www.host.foo.com
+User-Agent: curl/%VERSION
Accept: */*
Cookie: test2=yes; test=yes
GET /we/want/62?hoge=fuga HTTP/1.1
Host: www.host.foo.com
+User-Agent: curl/%VERSION
Accept: */*
Cookie: test2=yes; test=yes
diff --git a/tests/data/test63 b/tests/data/test63
index e7d7a4615..b330c6afe 100644
--- a/tests/data/test63
+++ b/tests/data/test63
@@ -40,13 +40,11 @@ proxy
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://we.want.that.site.com/63 HTTP/1.1
Host: we.want.that.site.com
Proxy-Authorization: Basic ZmFrZTp1c2Vy
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test64 b/tests/data/test64
index 804a6fa80..1e7a96eed 100644
--- a/tests/data/test64
+++ b/tests/data/test64
@@ -65,18 +65,16 @@ http://%HOSTIP:%HTTPPORT/64 -u testuser:testpass --digest
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /64 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /64 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="testrealm", nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca"
-User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test65 b/tests/data/test65
index f0b974213..606523183 100644
--- a/tests/data/test65
+++ b/tests/data/test65
@@ -65,18 +65,16 @@ http://%HOSTIP:%HTTPPORT/65 -u testuser:test2pass --digest
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /65 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /65 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="testrealm", nonce="2053604145", uri="/65", response="66d68d3251f1839576ba7c766cf9205b"
-User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test658 b/tests/data/test658
index 2ed6d6429..acf1846a6 100644
--- a/tests/data/test658
+++ b/tests/data/test658
@@ -38,9 +38,6 @@ http://%HOSTIP:%HTTPPORT/658
</client>
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /658 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test659 b/tests/data/test659
index 048c0d0f2..f191a8e89 100644
--- a/tests/data/test659
+++ b/tests/data/test659
@@ -42,9 +42,6 @@ proxy
</client>
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://www.example.com:80/ HTTP/1.1
Host: www.example.com
diff --git a/tests/data/test66 b/tests/data/test66
index 7b9af2953..23bb9e9c1 100644
--- a/tests/data/test66
+++ b/tests/data/test66
@@ -29,12 +29,10 @@ http://%HOSTIP:%HTTPPORT/66 --http0.9
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /66 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test662 b/tests/data/test662
index 53d97c39d..3140c61c1 100644
--- a/tests/data/test662
+++ b/tests/data/test662
@@ -59,17 +59,16 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://example.com/please/gimme/662 HTTP/1.1
Host: example.com
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://example.net/tes%20t%20case=/6620002 HTTP/1.1
Host: example.net
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test663 b/tests/data/test663
index c9c05a02d..487be2503 100644
--- a/tests/data/test663
+++ b/tests/data/test663
@@ -63,17 +63,16 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://example.com/gimme/663?foobar HTTP/1.1
Host: example.com
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://example.net/there/tes%20t%20case=/6630002?+yes+no HTTP/1.1
Host: example.net
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test669 b/tests/data/test669
index aaae2c51d..47b974ca3 100644
--- a/tests/data/test669
+++ b/tests/data/test669
@@ -30,22 +30,18 @@ HTTP custom Content-Type with parameter
<command>
http://%HOSTIP:%HTTPPORT/we/want/669 -H 'Content-type: multipart/form-data; charset=utf-8' -F name=daniel -F tool=curl
</command>
-</file>
</client>
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<strippart>
s/^--------------------------[a-z0-9]*/------------------------------/
s/boundary=------------------------[a-z0-9]*/boundary=----------------------------/
</strippart>
<protocol>
POST /we/want/669 HTTP/1.1
-User-Agent: curl/7.10.4 (i686-pc-linux-gnu) libcurl/7.10.4 OpenSSL/0.9.7a ipv6 zlib/1.1.3
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 242
Content-Type: multipart/form-data; charset=utf-8; boundary=----------------------------
diff --git a/tests/data/test67 b/tests/data/test67
index c0ccaf8f8..8138c7418 100644
--- a/tests/data/test67
+++ b/tests/data/test67
@@ -82,20 +82,17 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /67 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
GET /67 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAADj3hs3u3j0kgJqCrLM+74BmaoNHDfIJjHRlc3R1c2VyY3VybGhvc3Q=
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test674 b/tests/data/test674
index d1f1a8654..38ed39ef5 100644
--- a/tests/data/test674
+++ b/tests/data/test674
@@ -39,9 +39,6 @@ http://%HOSTIP:%HTTPPORT/674
</client>
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /674 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
diff --git a/tests/data/test68 b/tests/data/test68
index 1eaff6e7d..57ab2580c 100644
--- a/tests/data/test68
+++ b/tests/data/test68
@@ -81,20 +81,17 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /68 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
GET /68 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAADj3hs3u3j0kgJqCrLM+74BmaoNHDfIJjHRlc3R1c2VyY3VybGhvc3Q=
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test69 b/tests/data/test69
index 309f0394a..cc3178a6c 100644
--- a/tests/data/test69
+++ b/tests/data/test69
@@ -98,25 +98,22 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /69 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
GET /69 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
GET /69 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAADj3hs3u3j0kgJqCrLM+74BmaoNHDfIJjHRlc3R1c2VyY3VybGhvc3Q=
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test7 b/tests/data/test7
index 62731de13..317b235b9 100644
--- a/tests/data/test7
+++ b/tests/data/test7
@@ -38,12 +38,10 @@ http://%HOSTIP:%HTTPPORT/we/want/7 -b none -D log/heads7.txt
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/7 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test70 b/tests/data/test70
index 9057d6a4b..7057153e9 100644
--- a/tests/data/test70
+++ b/tests/data/test70
@@ -68,19 +68,16 @@ http://%HOSTIP:%HTTPPORT/70 -u testuser:testpass --anyauth
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /70 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
GET /70 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="testrealm", nonce="1053604199", uri="/70", response="2c9a6f00af0d86497b177b90e90c688a"
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test700 b/tests/data/test700
index ac63fa59a..f43590db3 100644
--- a/tests/data/test700
+++ b/tests/data/test700
@@ -44,12 +44,10 @@ HTTP GET via SOCKS4 proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /700 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test701 b/tests/data/test701
index 799597f38..3b687ff01 100644
--- a/tests/data/test701
+++ b/tests/data/test701
@@ -44,12 +44,10 @@ HTTP GET via SOCKS5 proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /701 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test702 b/tests/data/test702
index 1c18d0976..dd84ffe26 100644
--- a/tests/data/test702
+++ b/tests/data/test702
@@ -38,7 +38,7 @@ Attempt connect to non-listening HTTP server via SOCKS4 proxy
# Verify data after the test has been "shot"
<verify>
<errorcode>
-7
+97
</errorcode>
</verify>
</testcase>
diff --git a/tests/data/test703 b/tests/data/test703
index d7be71393..3c3487aee 100644
--- a/tests/data/test703
+++ b/tests/data/test703
@@ -38,7 +38,7 @@ Attempt connect to non-listening HTTP server via SOCKS5 proxy
# Verify data after the test has been "shot"
<verify>
<errorcode>
-7
+97
</errorcode>
</verify>
</testcase>
diff --git a/tests/data/test708 b/tests/data/test708
index e8bffc365..85aa95ed4 100644
--- a/tests/data/test708
+++ b/tests/data/test708
@@ -47,12 +47,10 @@ http://%HOSTIP:%HTTPPORT/708
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /708 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test709 b/tests/data/test709
index fa7fbc017..a2631521c 100644
--- a/tests/data/test709
+++ b/tests/data/test709
@@ -47,12 +47,10 @@ http://%HOSTIP:%HTTPPORT/709
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /709 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test710 b/tests/data/test710
index 884eb50a0..92df2f358 100644
--- a/tests/data/test710
+++ b/tests/data/test710
@@ -44,12 +44,10 @@ http://%HOSTIP:%HTTPPORT/710 --proxy socks5://%HOSTIP:%SOCKSPORT
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /710 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test716 b/tests/data/test716
index 96167de5c..531e272fa 100644
--- a/tests/data/test716
+++ b/tests/data/test716
@@ -39,7 +39,7 @@ http://hohoho.example.com:99/716 -x socks5://AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
# Verify data after the test has been "shot"
<verify>
<errorcode>
-43
+97
</errorcode>
</verify>
</testcase>
diff --git a/tests/data/test717 b/tests/data/test717
index dae50d9f2..5de8fcb69 100644
--- a/tests/data/test717
+++ b/tests/data/test717
@@ -55,12 +55,10 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /717 HTTP/1.1
Host: %HOSTIP:1
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test72 b/tests/data/test72
index 8e3adaa50..1160121b2 100644
--- a/tests/data/test72
+++ b/tests/data/test72
@@ -67,19 +67,16 @@ http://%HOSTIP:%HTTPPORT/72 -u testuser:testpass --anyauth
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /72 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
GET /72 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="testrealm", nonce="1053604199", uri="/72", response="9fcd1330377365a09bbcb33b2cbb25bd"
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test73 b/tests/data/test73
index 70408a865..8d830e83d 100644
--- a/tests/data/test73
+++ b/tests/data/test73
@@ -35,18 +35,16 @@ http://%HOSTIP:%HTTPPORT/we/want/73 -c log/jar73.txt -H "Host: host.NOT_DISCLOSE
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/73 HTTP/1.1
Host: host.NOT_DISCLOSED.se
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
<file name="log/jar73.txt" mode="text">
# Netscape HTTP Cookie File
-# https://curl.haxx.se/docs/http-cookies.html
+# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
.NOT_DISCLOSED.se TRUE / FALSE 0 IPCZQX01af0fca5c 000010008168c200d25dfc4b
diff --git a/tests/data/test74 b/tests/data/test74
index dbe0e9c13..1a7d73fc3 100644
--- a/tests/data/test74
+++ b/tests/data/test74
@@ -50,16 +50,15 @@ HTTP, urlglob {}-retrieval and -o #[num] usage
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /74 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /740001 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test75 b/tests/data/test75
index 62aeb119d..7bee04443 100644
--- a/tests/data/test75
+++ b/tests/data/test75
@@ -32,9 +32,6 @@ HTTP, urlglob retrieval with bad range
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<errorcode>
3
</errorcode>
diff --git a/tests/data/test76 b/tests/data/test76
index b6c47cd88..fc4a30d03 100644
--- a/tests/data/test76
+++ b/tests/data/test76
@@ -29,9 +29,6 @@ http://%HOSTIP:%NOLISTENPORT/76/ -O
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<errorcode>
23
</errorcode>
diff --git a/tests/data/test77 b/tests/data/test77
index 6a92158c8..81ea63720 100644
--- a/tests/data/test77
+++ b/tests/data/test77
@@ -42,12 +42,10 @@ http://%HOSTIP:%HTTPPORT/77 -z "dec 12 12:00:00 1999 GMT"
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /77 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
If-Modified-Since: Sun, 12 Dec 1999 12:00:00 GMT
diff --git a/tests/data/test78 b/tests/data/test78
index 6768000b4..d7f7d0fb0 100644
--- a/tests/data/test78
+++ b/tests/data/test78
@@ -54,12 +54,10 @@ http://%HOSTIP:%HTTPPORT/78 -z "dec 12 11:00:00 1999 GMT"
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /78 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
If-Modified-Since: Sun, 12 Dec 1999 11:00:00 GMT
diff --git a/tests/data/test79 b/tests/data/test79
index 9bc836681..e967bae0f 100644
--- a/tests/data/test79
+++ b/tests/data/test79
@@ -42,12 +42,10 @@ ftp://%HOSTIP:%HTTPPORT/we/want/that/page/79 -x %HOSTIP:%HTTPPORT
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET ftp://%HOSTIP:%HTTPPORT/we/want/that/page/79 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test8 b/tests/data/test8
index 2fc190060..02c6c0620 100644
--- a/tests/data/test8
+++ b/tests/data/test8
@@ -55,12 +55,10 @@ perl -e 'if ("%HOSTIP" !~ /\.0\.0\.1$/) {print "Test only works for HOSTIPs endi
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /we/want/8 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Cookie: name with space=is weird but; trailingspace=removed; cookie=perhaps; cookie=yes; foobar=name; blexp=yesyes
diff --git a/tests/data/test80 b/tests/data/test80
index 3e61eddde..26b74f78e 100644
--- a/tests/data/test80
+++ b/tests/data/test80
@@ -63,14 +63,11 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<proxy>
CONNECT test.80:%HTTPPORT HTTP/1.0
Host: test.80:%HTTPPORT
Proxy-Authorization: Basic eW91YXJlOnlvdXJzZWxm
-User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
</proxy>
@@ -78,7 +75,7 @@ Proxy-Connection: Keep-Alive
GET /we/want/that/page/80 HTTP/1.1
Host: test.80:%HTTPPORT
Authorization: Basic aWFtOm15c2VsZg==
-User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test81 b/tests/data/test81
index 29e558d9c..6a4912557 100644
--- a/tests/data/test81
+++ b/tests/data/test81
@@ -82,21 +82,18 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://%HOSTIP:%HTTPPORT/81 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
GET http://%HOSTIP:%HTTPPORT/81 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAADj3hs3u3j0kgJqCrLM+74BmaoNHDfIJjHRlc3R1c2VyY3VybGhvc3Q=
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test82 b/tests/data/test82
index 88d5da84d..138c8ee40 100644
--- a/tests/data/test82
+++ b/tests/data/test82
@@ -41,14 +41,11 @@ http://%HOSTIP:%HTTPPORT/82 --proxy-user testuser:testpass -x http://%HOSTIP:%HT
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://%HOSTIP:%HTTPPORT/82 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Proxy-Authorization: Basic dGVzdHVzZXI6dGVzdHBhc3M=
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test83 b/tests/data/test83
index 400e0a0f3..6d7446d18 100644
--- a/tests/data/test83
+++ b/tests/data/test83
@@ -60,13 +60,10 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<proxy>
CONNECT test.83:%HTTPPORT HTTP/1.1
Host: test.83:%HTTPPORT
-User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
</proxy>
@@ -74,7 +71,7 @@ Proxy-Connection: Keep-Alive
GET /we/want/that/page/83 HTTP/1.1
Host: test.83:%HTTPPORT
Authorization: Basic aWFtOm15OjtzZWxm
-User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test84 b/tests/data/test84
index 4cfde6dbb..37533e00d 100644
--- a/tests/data/test84
+++ b/tests/data/test84
@@ -41,14 +41,11 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://%HOSTIP:%HTTPPORT/we/want/that/page/84 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Basic aWFtOm15c2VsZg==
-User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test85 b/tests/data/test85
index 8b4cd6abc..ebdc37052 100644
--- a/tests/data/test85
+++ b/tests/data/test85
@@ -44,15 +44,12 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://%HOSTIP:%HTTPPORT/we/want/that/page/85 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Proxy-Authorization: Basic dGVzdGluZzp0aGlz
Authorization: Basic aWFtOm15c2VsZg==
-User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test86 b/tests/data/test86
index a69509ae2..26b66c431 100644
--- a/tests/data/test86
+++ b/tests/data/test86
@@ -64,23 +64,20 @@ HTTP, urlglob []-retrieval and -o #[num] usage
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /860001 HTTP/1.1
-User-Agent: curl/7.10.7-pre4 (i686-pc-linux-gnu) libcurl/7.10.7-pre4 OpenSSL/0.9.7a ipv6 zlib/1.1.3 GSS
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /860002 HTTP/1.1
-User-Agent: curl/7.10.7-pre4 (i686-pc-linux-gnu) libcurl/7.10.7-pre4 OpenSSL/0.9.7a ipv6 zlib/1.1.3 GSS
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /860003 HTTP/1.1
-User-Agent: curl/7.10.7-pre4 (i686-pc-linux-gnu) libcurl/7.10.7-pre4 OpenSSL/0.9.7a ipv6 zlib/1.1.3 GSS
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test88 b/tests/data/test88
index e2d019c06..40b0e8f4d 100644
--- a/tests/data/test88
+++ b/tests/data/test88
@@ -75,19 +75,17 @@ four is the number of lines
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /88 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 0
PUT /88 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: Digest username="testuser", realm="testrealm", nonce="1053604145", uri="/88", response="78a49fa53d0c228778297687d4168e71"
-User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 85
Expect: 100-continue
diff --git a/tests/data/test89 b/tests/data/test89
index fc620cb23..0537fa5d4 100644
--- a/tests/data/test89
+++ b/tests/data/test89
@@ -115,32 +115,29 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /89 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
GET /89 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAADj3hs3u3j0kgJqCrLM+74BmaoNHDfIJjHRlc3R1c2VyY3VybGhvc3Q=
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
GET /you/890010 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.10.8-pre1 (i686-pc-linux-gnu) libcurl/7.10.8-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3 GSS
+User-Agent: curl/%VERSION
Accept: */*
GET /you/890010 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADYzMjE3MzIxAAAAAAAAAAAAAAAAAAAAAEcJ4YHOeb5ga2TCPwDhkyUIuHjBUHcLaHRlc3R1c2VyY3VybGhvc3Q=
-User-Agent: curl/7.10.8-pre1 (i686-pc-linux-gnu) libcurl/7.10.8-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3 GSS
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test9 b/tests/data/test9
index 53fe25eda..adef69419 100644
--- a/tests/data/test9
+++ b/tests/data/test9
@@ -40,12 +40,12 @@ bar
# Verify data after the test has been "shot"
<verify>
<strip>
-^(User-Agent:|Content-Type: multipart/form-data;|------------).*
+^(Content-Type: multipart/form-data;|------------).*
</strip>
<protocol>
POST /we/want/9 HTTP/1.1
-User-Agent: curl/7.10.4 (i686-pc-linux-gnu) libcurl/7.10.4 OpenSSL/0.9.7a ipv6 zlib/1.1.3
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 407
Content-Type: multipart/form-data; boundary=----------------------------9ef8d6205763
diff --git a/tests/data/test90 b/tests/data/test90
index d40b5a571..91d569d08 100644
--- a/tests/data/test90
+++ b/tests/data/test90
@@ -153,40 +153,39 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /90 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /90 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
GET /90 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAADj3hs3u3j0kgJqCrLM+74BmaoNHDfIJjHRlc3R1c2VyY3VybGhvc3Q=
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
GET /you/900010 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
GET /you/900010 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.10.8-pre1 (i686-pc-linux-gnu) libcurl/7.10.8-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3 GSS
+User-Agent: curl/%VERSION
Accept: */*
GET /you/900010 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAACAAIAHAAAAAIAAgAeAAAAAAAAAAAAAAAhoIBADYzMjE3MzIxAAAAAAAAAAAAAAAAAAAAAEcJ4YHOeb5ga2TCPwDhkyUIuHjBUHcLaHRlc3R1c2VyY3VybGhvc3Q=
-User-Agent: curl/7.10.8-pre1 (i686-pc-linux-gnu) libcurl/7.10.8-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3 GSS
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test91 b/tests/data/test91
index 4942bfddf..314a65514 100644
--- a/tests/data/test91
+++ b/tests/data/test91
@@ -99,25 +99,22 @@ chkhostname curlhost
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /91 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
GET /91 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
GET /91 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAgACABwAAAABgAGAHgAAAAIAAgAfgAAAAAAAAAAAAAAhoIBADQzMjE1MzIxAAAAAAAAAAAAAAAAAAAAAKBS3rdGYZEGsqW8otYHWXWBxC5mCuFmYm15ZG9tYWlubXlzZWxmY3VybGhvc3Q=
-User-Agent: curl/7.10.6-pre1 (i686-pc-linux-gnu) libcurl/7.10.6-pre1 OpenSSL/0.9.7a ipv6 zlib/1.1.3
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test92 b/tests/data/test92
index 728d271b0..7e03f0a12 100644
--- a/tests/data/test92
+++ b/tests/data/test92
@@ -54,13 +54,11 @@ http://%HOSTIP:%HTTPPORT/want/92 -C 87
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /want/92 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Range: bytes=87-
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/data/test93 b/tests/data/test93
index 58e47bc6b..684e56cd4 100644
--- a/tests/data/test93
+++ b/tests/data/test93
@@ -39,12 +39,10 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET http://%HOSTIP:%HTTPPORT/93 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
diff --git a/tests/data/test94 b/tests/data/test94
index 4ca53c63b..6d54e7870 100644
--- a/tests/data/test94
+++ b/tests/data/test94
@@ -45,13 +45,10 @@ https://test.anything.really.com:94 --proxy1.0 %HOSTIP:%HTTPPORT
<errorcode>
56
</errorcode>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
CONNECT test.anything.really.com:94 HTTP/1.0
-User-Agent: curl/7.11.0-CVS (i686-pc-linux-gnu) libcurl/7.11.0-CVS OpenSSL/0.9.6b ipv6 zlib/1.1.4
Host: test.anything.really.com:94
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
</protocol>
diff --git a/tests/data/test95 b/tests/data/test95
index afc00aede..0b16c3cd1 100644
--- a/tests/data/test95
+++ b/tests/data/test95
@@ -60,20 +60,17 @@ proxy
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<proxy>
CONNECT test.95:%HTTPPORT HTTP/1.1
-User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3
Host: test.95:%HTTPPORT
+User-Agent: curl/%VERSION
Proxy-Connection: Keep-Alive
</proxy>
<protocol nonewline="yes">
POST /we/want/that/page/95 HTTP/1.1
-User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3
Host: test.95:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 27
Content-Type: application/x-www-form-urlencoded
diff --git a/tests/data/test97 b/tests/data/test97
index c1065bb19..d76941196 100644
--- a/tests/data/test97
+++ b/tests/data/test97
@@ -36,12 +36,10 @@ HTTP POST with custom content-type
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol nonewline="yes">
POST /97 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Type: silly/type
Content-Length: 14
diff --git a/tests/data/test970 b/tests/data/test970
index c0a88a798..ab1fc53a6 100644
--- a/tests/data/test970
+++ b/tests/data/test970
@@ -51,17 +51,15 @@ http://%HOSTIP:%HTTPPORT/970 --write-out '%{json}' -o log/out970
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /970 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
<stdout nonewline="yes">
-{"url_effective":"http://%HOSTIP:%HTTPPORT/970","method":"GET","http_code":200,"response_code":200,"http_connect":0,"time_total":0.000013,"time_namelookup":0.000013,"time_connect":0.000013,"time_appconnect":0.000013,"time_pretransfer":0.000013,"time_starttransfer":0.000013,"size_header":4019,"size_request":4019,"size_download":445,"size_upload":0,"speed_download":13,"speed_upload":13,"content_type":"text/html","num_connects":1,"time_redirect":0.000013,"num_redirects":0,"ssl_verify_result":0,"proxy_ssl_verify_result":0,"filename_effective":"log/out970","remote_ip":"%HOSTIP","remote_port":%HTTPPORT,"local_ip":"127.0.0.1","local_port":13,"http_version":"1.1","scheme":"HTTP","curl_version":"curl-unit-test-fake-version"}
+{"url_effective":"http://%HOSTIP:%HTTPPORT/970","method":"GET","http_code":200,"response_code":200,"num_headers":9,"http_connect":0,"time_total":0.000013,"time_namelookup":0.000013,"time_connect":0.000013,"time_appconnect":0.000013,"time_pretransfer":0.000013,"time_starttransfer":0.000013,"size_header":4019,"size_request":4019,"size_download":445,"size_upload":0,"speed_download":13,"speed_upload":13,"content_type":"text/html","num_connects":1,"time_redirect":0.000013,"num_redirects":0,"ssl_verify_result":0,"proxy_ssl_verify_result":0,"filename_effective":"log/out970","remote_ip":"%HOSTIP","remote_port":%HTTPPORT,"local_ip":"127.0.0.1","local_port":13,"http_version":"1.1","scheme":"HTTP","curl_version":"curl-unit-test-fake-version"}
</stdout>
</verify>
</testcase>
diff --git a/tests/data/test971 b/tests/data/test971
index de134e8e6..dada92001 100644
--- a/tests/data/test971
+++ b/tests/data/test971
@@ -22,4 +22,9 @@ Verify that options-in-versions and docs/cmdline-opts are in sync
</command>
</client>
+<verify>
+<stderr>
+ok
+</stderr>
+</verify>
</testcase>
diff --git a/tests/data/test98 b/tests/data/test98
index b6d1182c6..ef0cded2f 100644
--- a/tests/data/test98
+++ b/tests/data/test98
@@ -39,12 +39,10 @@ data on stdin
#
# Verify data after the test has been "shot"
<verify>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
PUT /98 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
Accept: */*
Content-Length: 14
Expect: 100-continue
diff --git a/tests/data/test99 b/tests/data/test99
index 9797600cf..2bbee7809 100644
--- a/tests/data/test99
+++ b/tests/data/test99
@@ -55,13 +55,11 @@ http://%HOSTIP:%HTTPPORT/99 -C 9999999999
<errorcode>
33
</errorcode>
-<strip>
-^User-Agent:.*
-</strip>
<protocol>
GET /99 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Range: bytes=9999999999-
+User-Agent: curl/%VERSION
Accept: */*
</protocol>
diff --git a/tests/dictserver.py.in b/tests/dictserver.py.in
index e08617f5e..ea45ba80c 100755
--- a/tests/dictserver.py.in
+++ b/tests/dictserver.py.in
@@ -11,7 +11,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -26,16 +26,19 @@
from __future__ import (absolute_import, division, print_function,
unicode_literals)
+
import argparse
+import logging
import os
import sys
-import logging
+
+from util import ClosingFileHandler
+
try: # Python 2
import SocketServer as socketserver
except ImportError: # Python 3
import socketserver
-
log = logging.getLogger(__name__)
HOST = "localhost"
@@ -138,7 +141,7 @@ def setup_logging(options):
# Write out to a logfile
if options.logfile:
- handler = logging.FileHandler(options.logfile, mode="w")
+ handler = ClosingFileHandler(options.logfile)
handler.setFormatter(formatter)
handler.setLevel(logging.DEBUG)
root_logger.addHandler(handler)
diff --git a/tests/directories.pm b/tests/directories.pm
index da6c76746..a55d8180c 100644
--- a/tests/directories.pm
+++ b/tests/directories.pm
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/disable-scan.pl.in b/tests/disable-scan.pl.in
index 12600f336..41fc14056 100755
--- a/tests/disable-scan.pl.in
+++ b/tests/disable-scan.pl.in
@@ -6,11 +6,11 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 2010-2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 2010 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/error-codes.pl.in b/tests/error-codes.pl.in
index d9ddbcdfa..73873d393 100644
--- a/tests/error-codes.pl.in
+++ b/tests/error-codes.pl.in
@@ -6,11 +6,11 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 2010-2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 2010 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/extern-scan.pl.in b/tests/extern-scan.pl.in
index 53725dc9b..64282d504 100755
--- a/tests/extern-scan.pl.in
+++ b/tests/extern-scan.pl.in
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/ftp.pm b/tests/ftp.pm
index 971be199f..50c82b837 100644
--- a/tests/ftp.pm
+++ b/tests/ftp.pm
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/ftpserver.pl.in b/tests/ftpserver.pl.in
index ae9ac05f4..ed6868b1f 100755
--- a/tests/ftpserver.pl.in
+++ b/tests/ftpserver.pl.in
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -145,6 +145,7 @@ my $nodataconn; # set if ftp srvr doesn't establish or accepts data channel
my $nodataconn425; # set if ftp srvr doesn't establish data ch and replies 425
my $nodataconn421; # set if ftp srvr doesn't establish data ch and replies 421
my $nodataconn150; # set if ftp srvr doesn't establish data ch and replies 150
+my $storeresp;
my @capabilities; # set if server supports capability commands
my @auth_mechs; # set if server supports authentication commands
my %fulltextreply; #
@@ -2413,6 +2414,10 @@ sub STOR_ftp {
logmsg "No support for: $line";
last;
}
+ if($storeresp) {
+ # abort early
+ last;
+ }
}
if($nosave) {
print FILE "$ulsize bytes would've been stored here\n";
@@ -2420,7 +2425,12 @@ sub STOR_ftp {
close(FILE);
close_dataconn($disc);
logmsg "received $ulsize bytes upload\n";
- sendcontrol "226 File transfer complete\r\n";
+ if($storeresp) {
+ sendcontrol "$storeresp\r\n";
+ }
+ else {
+ sendcontrol "226 File transfer complete\r\n";
+ }
return 0;
}
@@ -2784,6 +2794,7 @@ sub customize {
$nodataconn425 = 0; # default is to not send 425 without data channel
$nodataconn421 = 0; # default is to not send 421 without data channel
$nodataconn150 = 0; # default is to not send 150 without data channel
+ $storeresp = ""; # send as ultimate STOR response
@capabilities = (); # default is to not support capability commands
@auth_mechs = (); # default is to not support authentication commands
%fulltextreply = ();#
@@ -2866,6 +2877,10 @@ sub customize {
logmsg "FTPD: instructed to use NODATACONN\n";
$nodataconn=1;
}
+ elsif($_ =~ /^STOR (.*)/) {
+ $storeresp=$1;
+ logmsg "FTPD: instructed to use respond to STOR with '$storeresp'\n";
+ }
elsif($_ =~ /CAPA (.*)/) {
logmsg "FTPD: instructed to support CAPABILITY command\n";
@capabilities = split(/ (?!(?:[^" ]|[^"] [^"])+")/, $1);
diff --git a/tests/fuzz/download_fuzzer.sh b/tests/fuzz/download_fuzzer.sh
index a0669e169..77f9cda40 100755
--- a/tests/fuzz/download_fuzzer.sh
+++ b/tests/fuzz/download_fuzzer.sh
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/getpart.pm b/tests/getpart.pm
index 9519888ee..5700ca7a0 100644
--- a/tests/getpart.pm
+++ b/tests/getpart.pm
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -28,12 +28,7 @@ my $xmlfile;
my $warning=0;
my $trace=0;
-sub decode_base64 {
- tr:A-Za-z0-9+/::cd; # remove non-base64 chars
- tr:A-Za-z0-9+/: -_:; # convert to uuencoded format
- my $len = pack("c", 32 + 0.75*length); # compute length byte
- return unpack("u", $len . $_); # uudecode and print
-}
+use MIME::Base64;
sub decode_hex {
my $s = $_;
diff --git a/tests/http2-server.pl.in b/tests/http2-server.pl.in
index 2358ad3fa..1dcc8a695 100755
--- a/tests/http2-server.pl.in
+++ b/tests/http2-server.pl.in
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/httpserver.pl.in b/tests/httpserver.pl.in
index 051982243..3e4c7b5bc 100755
--- a/tests/httpserver.pl.in
+++ b/tests/httpserver.pl.in
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/keywords.pl.in b/tests/keywords.pl.in
index 798f58194..51370fc9d 100755
--- a/tests/keywords.pl.in
+++ b/tests/keywords.pl.in
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/.gitignore b/tests/libtest/.gitignore
index c0077076d..62d9176d5 100644
--- a/tests/libtest/.gitignore
+++ b/tests/libtest/.gitignore
@@ -1,6 +1,6 @@
chkdecimalpoint
chkhostname
-lib[12][0-9][0-9][0-9]
+lib[123][0-9][0-9][0-9]
lib[56][0-9][0-9]
lib1521.c
libauthretry
diff --git a/tests/libtest/CMakeLists.txt b/tests/libtest/CMakeLists.txt
index 43ec8446e..6f858af31 100644
--- a/tests/libtest/CMakeLists.txt
+++ b/tests/libtest/CMakeLists.txt
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/Makefile.am b/tests/libtest/Makefile.am
index 590c77a7e..b36fbcd21 100644
--- a/tests/libtest/Makefile.am
+++ b/tests/libtest/Makefile.am
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc
index 2c9c66539..1628671c7 100644
--- a/tests/libtest/Makefile.inc
+++ b/tests/libtest/Makefile.inc
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -39,7 +39,7 @@ noinst_PROGRAMS = chkhostname libauthretry libntlmconnect \
chkdecimalpoint \
lib500 lib501 lib502 lib503 lib504 lib505 lib506 lib507 lib508 lib509 \
lib510 lib511 lib512 lib513 lib514 lib515 lib516 lib517 lib518 lib519 \
- lib520 lib521 lib523 lib524 lib525 lib526 lib527 lib529 lib530 lib532 \
+ lib520 lib521 lib523 lib524 lib525 lib526 lib527 lib529 lib532 \
lib533 lib537 lib539 lib540 lib541 lib542 lib543 lib544 lib545 \
lib547 lib548 lib549 lib552 lib553 lib554 lib555 lib556 lib557 lib558 \
lib559 lib560 lib562 lib564 lib565 lib566 lib567 lib568 lib569 lib570 \
@@ -54,18 +54,19 @@ noinst_PROGRAMS = chkhostname libauthretry libntlmconnect \
lib1518 lib1520 lib1521 lib1522 lib1523 \
lib1525 lib1526 lib1527 lib1528 lib1529 lib1530 lib1531 lib1532 lib1533 \
lib1534 lib1535 lib1536 lib1537 lib1538 lib1539 \
- lib1540 lib1541 \
+ lib1540 \
lib1550 lib1551 lib1552 lib1553 lib1554 lib1555 lib1556 lib1557 \
lib1558 lib1559 lib1560 lib1564 lib1565 lib1567 \
lib1591 lib1592 lib1593 lib1594 lib1596 \
- lib1900 lib1905 lib1906 lib1907 lib1908 lib1910 \
- lib2033 lib3010
+ lib1905 lib1906 lib1907 lib1908 lib1910 lib1911 lib1912 lib1913 \
+ lib1915 \
+ lib3010
chkdecimalpoint_SOURCES = chkdecimalpoint.c ../../lib/mprintf.c \
../../lib/curl_ctype.c ../../lib/dynbuf.c ../../lib/strdup.c
chkdecimalpoint_LDADD =
chkdecimalpoint_CPPFLAGS = $(AM_CPPFLAGS) -DCURL_STATICLIB \
- -DCURLX_NO_MEMORY_CALLBACKS
+ -DCURLX_NO_MEMORY_CALLBACKS -DBUILDING_LIBCURL
chkhostname_SOURCES = chkhostname.c ../../lib/curl_gethostname.c
chkhostname_LDADD = @CURL_NETWORK_LIBS@
@@ -172,10 +173,6 @@ lib529_SOURCES = lib525.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) $(MULTIBYTE)
lib529_LDADD = $(TESTUTIL_LIBS)
lib529_CPPFLAGS = $(AM_CPPFLAGS) -DLIB529
-lib530_SOURCES = lib530.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
-lib530_LDADD = $(TESTUTIL_LIBS)
-lib530_CPPFLAGS = $(AM_CPPFLAGS) -DLIB530
-
lib532_SOURCES = lib526.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib532_LDADD = $(TESTUTIL_LIBS)
lib532_CPPFLAGS = $(AM_CPPFLAGS) -DLIB532
@@ -554,10 +551,6 @@ lib1540_SOURCES = lib1540.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib1540_LDADD = $(TESTUTIL_LIBS)
lib1540_CPPFLAGS = $(AM_CPPFLAGS)
-lib1541_SOURCES = lib1541.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
-lib1541_LDADD = $(TESTUTIL_LIBS)
-lib1541_CPPFLAGS = $(AM_CPPFLAGS)
-
lib1550_SOURCES = lib1550.c $(SUPPORTFILES)
lib1550_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1517
@@ -625,10 +618,6 @@ lib1596_SOURCES = lib1594.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib1596_LDADD = $(TESTUTIL_LIBS)
lib1596_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1596
-lib1900_SOURCES = lib1900.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) $(MULTIBYTE)
-lib1900_LDADD = $(TESTUTIL_LIBS)
-lib1900_CPPFLAGS = $(AM_CPPFLAGS)
-
lib1905_SOURCES = lib1905.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib1905_LDADD = $(TESTUTIL_LIBS)
lib1905_CPPFLAGS = $(AM_CPPFLAGS)
@@ -649,9 +638,21 @@ lib1910_SOURCES = lib1910.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib1910_LDADD = $(TESTUTIL_LIBS)
lib1910_CPPFLAGS = $(AM_CPPFLAGS)
-lib2033_SOURCES = libntlmconnect.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
-lib2033_LDADD = $(TESTUTIL_LIBS)
-lib2033_CPPFLAGS = $(AM_CPPFLAGS) -DUSE_PIPELINING
+lib1911_SOURCES = lib1911.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib1911_LDADD = $(TESTUTIL_LIBS)
+lib1911_CPPFLAGS = $(AM_CPPFLAGS)
+
+lib1912_SOURCES = lib1912.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib1912_LDADD = $(TESTUTIL_LIBS)
+lib1912_CPPFLAGS = $(AM_CPPFLAGS)
+
+lib1913_SOURCES = lib1913.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib1913_LDADD = $(TESTUTIL_LIBS)
+lib1913_CPPFLAGS = $(AM_CPPFLAGS)
+
+lib1915_SOURCES = lib1915.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib1915_LDADD = $(TESTUTIL_LIBS)
+lib1915_CPPFLAGS = $(AM_CPPFLAGS)
lib3010_SOURCES = lib3010.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib3010_LDADD = $(TESTUTIL_LIBS)
diff --git a/tests/libtest/chkdecimalpoint.c b/tests/libtest/chkdecimalpoint.c
index 7bb77150f..4ab98cf4d 100644
--- a/tests/libtest/chkdecimalpoint.c
+++ b/tests/libtest/chkdecimalpoint.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/chkhostname.c b/tests/libtest/chkhostname.c
index 79e382b38..d36e8375d 100644
--- a/tests/libtest/chkhostname.c
+++ b/tests/libtest/chkhostname.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/first.c b/tests/libtest/first.c
index 2731ef8db..84369fca8 100644
--- a/tests/libtest/first.c
+++ b/tests/libtest/first.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1156.c b/tests/libtest/lib1156.c
index ff94d9cfd..9ffe19a79 100644
--- a/tests/libtest/lib1156.c
+++ b/tests/libtest/lib1156.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1500.c b/tests/libtest/lib1500.c
index 73d23a1b7..ed944a26b 100644
--- a/tests/libtest/lib1500.c
+++ b/tests/libtest/lib1500.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1501.c b/tests/libtest/lib1501.c
index 96094d699..a847c70d6 100644
--- a/tests/libtest/lib1501.c
+++ b/tests/libtest/lib1501.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1502.c b/tests/libtest/lib1502.c
index 6bde00a86..d10de9771 100644
--- a/tests/libtest/lib1502.c
+++ b/tests/libtest/lib1502.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1506.c b/tests/libtest/lib1506.c
index 1d5e8de4a..a49e5b4ab 100644
--- a/tests/libtest/lib1506.c
+++ b/tests/libtest/lib1506.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2013 - 2018, Linus Nielsen Feltzing <linus@haxx.se>
+ * Copyright (C) 2013 - 2020, Linus Nielsen Feltzing <linus@haxx.se>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1507.c b/tests/libtest/lib1507.c
index 20cc5f0a4..019b4f113 100644
--- a/tests/libtest/lib1507.c
+++ b/tests/libtest/lib1507.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1508.c b/tests/libtest/lib1508.c
index 09d24d8dc..bbd200b6e 100644
--- a/tests/libtest/lib1508.c
+++ b/tests/libtest/lib1508.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1509.c b/tests/libtest/lib1509.c
index 2bc8c9ffa..02e84f56a 100644
--- a/tests/libtest/lib1509.c
+++ b/tests/libtest/lib1509.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1510.c b/tests/libtest/lib1510.c
index 4c7b670a0..af01c4d82 100644
--- a/tests/libtest/lib1510.c
+++ b/tests/libtest/lib1510.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2013 - 2018, Linus Nielsen Feltzing <linus@haxx.se>
+ * Copyright (C) 2013 - 2020, Linus Nielsen Feltzing <linus@haxx.se>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1511.c b/tests/libtest/lib1511.c
index e1840e76f..a813f8968 100644
--- a/tests/libtest/lib1511.c
+++ b/tests/libtest/lib1511.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1512.c b/tests/libtest/lib1512.c
index 0b71ad3f5..6879c4d43 100644
--- a/tests/libtest/lib1512.c
+++ b/tests/libtest/lib1512.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2013 - 2018, Linus Nielsen Feltzing <linus@haxx.se>
+ * Copyright (C) 2013 - 2020, Linus Nielsen Feltzing <linus@haxx.se>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1513.c b/tests/libtest/lib1513.c
index 932ca7208..f75ca0866 100644
--- a/tests/libtest/lib1513.c
+++ b/tests/libtest/lib1513.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2015, 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1514.c b/tests/libtest/lib1514.c
index dd84d109f..ee9b4e9ba 100644
--- a/tests/libtest/lib1514.c
+++ b/tests/libtest/lib1514.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1515.c b/tests/libtest/lib1515.c
index 4e578a42e..4aede606d 100644
--- a/tests/libtest/lib1515.c
+++ b/tests/libtest/lib1515.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1517.c b/tests/libtest/lib1517.c
index ea622b046..173f65cbf 100644
--- a/tests/libtest/lib1517.c
+++ b/tests/libtest/lib1517.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1518.c b/tests/libtest/lib1518.c
index 1751b583d..1f2fe3de0 100644
--- a/tests/libtest/lib1518.c
+++ b/tests/libtest/lib1518.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1520.c b/tests/libtest/lib1520.c
index 779aeafcd..dda2a2fe1 100644
--- a/tests/libtest/lib1520.c
+++ b/tests/libtest/lib1520.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1522.c b/tests/libtest/lib1522.c
index 6df152f1f..e070e80f4 100644
--- a/tests/libtest/lib1522.c
+++ b/tests/libtest/lib1522.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1523.c b/tests/libtest/lib1523.c
index 170527d84..bd45b8471 100644
--- a/tests/libtest/lib1523.c
+++ b/tests/libtest/lib1523.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -56,8 +56,10 @@ static CURLcode run(CURL *hnd, long limit, long time)
int test(char *URL)
{
CURLcode ret;
- CURL *hnd = curl_easy_init();
+ CURL *hnd;
char buffer[CURL_ERROR_SIZE];
+ curl_global_init(CURL_GLOBAL_ALL);
+ hnd = curl_easy_init();
curl_easy_setopt(hnd, CURLOPT_URL, URL);
curl_easy_setopt(hnd, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(hnd, CURLOPT_ERRORBUFFER, buffer);
@@ -77,6 +79,7 @@ int test(char *URL)
printf("End: %d\n", time(NULL));
curl_easy_cleanup(hnd);
+ curl_global_cleanup();
return (int)ret;
}
diff --git a/tests/libtest/lib1525.c b/tests/libtest/lib1525.c
index 551d04e02..e8aff9865 100644
--- a/tests/libtest/lib1525.c
+++ b/tests/libtest/lib1525.c
@@ -10,7 +10,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1526.c b/tests/libtest/lib1526.c
index d94c03cf4..1fec7043f 100644
--- a/tests/libtest/lib1526.c
+++ b/tests/libtest/lib1526.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1527.c b/tests/libtest/lib1527.c
index c50c2fa23..32e9fb57c 100644
--- a/tests/libtest/lib1527.c
+++ b/tests/libtest/lib1527.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1528.c b/tests/libtest/lib1528.c
index a130c49af..98a332c5b 100644
--- a/tests/libtest/lib1528.c
+++ b/tests/libtest/lib1528.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1529.c b/tests/libtest/lib1529.c
index 8d2210e25..006355233 100644
--- a/tests/libtest/lib1529.c
+++ b/tests/libtest/lib1529.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1530.c b/tests/libtest/lib1530.c
index 6fc69f251..778dd38f5 100644
--- a/tests/libtest/lib1530.c
+++ b/tests/libtest/lib1530.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1531.c b/tests/libtest/lib1531.c
index 73b3f0a91..6d7ea6aa9 100644
--- a/tests/libtest/lib1531.c
+++ b/tests/libtest/lib1531.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1532.c b/tests/libtest/lib1532.c
index 4a3ff3245..c937d2b23 100644
--- a/tests/libtest/lib1532.c
+++ b/tests/libtest/lib1532.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1533.c b/tests/libtest/lib1533.c
index 7a4aafc64..21a3eacba 100644
--- a/tests/libtest/lib1533.c
+++ b/tests/libtest/lib1533.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1534.c b/tests/libtest/lib1534.c
index 61e72abb0..738d5dd63 100644
--- a/tests/libtest/lib1534.c
+++ b/tests/libtest/lib1534.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1535.c b/tests/libtest/lib1535.c
index b448466dd..eb0fa361b 100644
--- a/tests/libtest/lib1535.c
+++ b/tests/libtest/lib1535.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1536.c b/tests/libtest/lib1536.c
index 5bee299cc..7a1aa9bfa 100644
--- a/tests/libtest/lib1536.c
+++ b/tests/libtest/lib1536.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1537.c b/tests/libtest/lib1537.c
index 7c5dde042..cca3b91a4 100644
--- a/tests/libtest/lib1537.c
+++ b/tests/libtest/lib1537.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1538.c b/tests/libtest/lib1538.c
index 91481e88d..a439a06bf 100644
--- a/tests/libtest/lib1538.c
+++ b/tests/libtest/lib1538.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -31,12 +31,12 @@ int test(char *URL)
CURLSHcode shareret;
(void)URL;
- curl_easy_strerror(INT_MAX);
- curl_multi_strerror(INT_MAX);
- curl_share_strerror(INT_MAX);
- curl_easy_strerror(-INT_MAX);
- curl_multi_strerror(-INT_MAX);
- curl_share_strerror(-INT_MAX);
+ curl_easy_strerror((CURLcode)INT_MAX);
+ curl_multi_strerror((CURLMcode)INT_MAX);
+ curl_share_strerror((CURLSHcode)INT_MAX);
+ curl_easy_strerror((CURLcode)-INT_MAX);
+ curl_multi_strerror((CURLMcode)-INT_MAX);
+ curl_share_strerror((CURLSHcode)-INT_MAX);
for(easyret = CURLE_OK; easyret <= CURL_LAST; easyret++) {
printf("e%d: %s\n", (int)easyret, curl_easy_strerror(easyret));
}
diff --git a/tests/libtest/lib1540.c b/tests/libtest/lib1540.c
index d0e4ca9b6..8c4304ea0 100644
--- a/tests/libtest/lib1540.c
+++ b/tests/libtest/lib1540.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1541.c b/tests/libtest/lib1541.c
index f3b41f5be..ef4baca4e 100644
--- a/tests/libtest/lib1541.c
+++ b/tests/libtest/lib1541.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -19,6 +19,13 @@
* KIND, either express or implied.
*
***************************************************************************/
+/*
+ * KNOW_BUGS "A shared connection cache is not thread-safe"
+ *
+ * This source code was used to verify shared connection cache but since this
+ * is a known issue the test is no longer built or run. This code is here to
+ * allow for testing once someone gets to work on fixing this.
+ */
#include "test.h"
#include "testutil.h"
diff --git a/tests/libtest/lib1550.c b/tests/libtest/lib1550.c
index 1df5503fd..8e2fdd6e9 100644
--- a/tests/libtest/lib1550.c
+++ b/tests/libtest/lib1550.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -32,7 +32,7 @@ int test(char *URL)
static const char * const bl_servers[] =
{"Microsoft-IIS/6.0", "nginx/0.8.54", NULL};
static const char * const bl_sites[] =
- {"curl.haxx.se:443", "example.com:80", NULL};
+ {"curl.se:443", "example.com:80", NULL};
global_init(CURL_GLOBAL_ALL);
handle = curl_multi_init();
diff --git a/tests/libtest/lib1551.c b/tests/libtest/lib1551.c
index edd6e9c8f..bdd101942 100644
--- a/tests/libtest/lib1551.c
+++ b/tests/libtest/lib1551.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1552.c b/tests/libtest/lib1552.c
index 02c4ea860..ce783d7f4 100644
--- a/tests/libtest/lib1552.c
+++ b/tests/libtest/lib1552.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1553.c b/tests/libtest/lib1553.c
index 60be7c1a7..65292a7e5 100644
--- a/tests/libtest/lib1553.c
+++ b/tests/libtest/lib1553.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1554.c b/tests/libtest/lib1554.c
index a8198803b..a18d548b0 100644
--- a/tests/libtest/lib1554.c
+++ b/tests/libtest/lib1554.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1555.c b/tests/libtest/lib1555.c
index f7193b5be..0c00574a9 100644
--- a/tests/libtest/lib1555.c
+++ b/tests/libtest/lib1555.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1556.c b/tests/libtest/lib1556.c
index fa0e60e24..38de9ef8e 100644
--- a/tests/libtest/lib1556.c
+++ b/tests/libtest/lib1556.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1557.c b/tests/libtest/lib1557.c
index d7132ad04..1f0ceedf3 100644
--- a/tests/libtest/lib1557.c
+++ b/tests/libtest/lib1557.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1558.c b/tests/libtest/lib1558.c
index 2305f4d76..610339b63 100644
--- a/tests/libtest/lib1558.c
+++ b/tests/libtest/lib1558.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -49,7 +49,7 @@ int test(char *URL)
goto test_cleanup;
}
- printf("Protocol: %x\n", protocol);
+ printf("Protocol: %lx\n", protocol);
curl_easy_cleanup(curl);
curl_global_cleanup();
diff --git a/tests/libtest/lib1559.c b/tests/libtest/lib1559.c
index e1b417548..28328e493 100644
--- a/tests/libtest/lib1559.c
+++ b/tests/libtest/lib1559.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1560.c b/tests/libtest/lib1560.c
index d158534d7..c81400242 100644
--- a/tests/libtest/lib1560.c
+++ b/tests/libtest/lib1560.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -479,6 +479,13 @@ static int checkurl(const char *url, const char *out)
/* !checksrc! disable SPACEBEFORECOMMA 1 */
static struct setcase set_parts_list[] = {
{"https://example.com/",
+ "query=Al2cO3tDkcDZ3EWE5Lh+LX8TPHs,", /* contains '+' */
+ "https://example.com/?Al2cO3tDkcDZ3EWE5Lh%2bLX8TPHs",
+ CURLU_URLDECODE, /* decode on get */
+ CURLU_URLENCODE, /* encode on set */
+ CURLUE_OK, CURLUE_OK},
+
+ {"https://example.com/",
/* Set a 41 bytes scheme. That's too long so the old scheme remains set. */
"scheme=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc,",
"https://example.com/",
@@ -638,7 +645,7 @@ static CURLUPart part2id(char *part)
return CURLUPART_FRAGMENT;
if(!strcmp("zoneid", part))
return CURLUPART_ZONEID;
- return 9999; /* bad input => bad output */
+ return (CURLUPart)9999; /* bad input => bad output */
}
static CURLUcode updateurl(CURLU *u, const char *cmd, unsigned int setflags)
@@ -686,6 +693,14 @@ static CURLUcode updateurl(CURLU *u, const char *cmd, unsigned int setflags)
}
static struct redircase set_url_list[] = {
+ {"http://example.org/static/favicon/wikipedia.ico",
+ "//fake.example.com/licenses/by-sa/3.0/",
+ "http://fake.example.com/licenses/by-sa/3.0/",
+ 0, 0, 0},
+ {"https://example.org/static/favicon/wikipedia.ico",
+ "//fake.example.com/licenses/by-sa/3.0/",
+ "https://fake.example.com/licenses/by-sa/3.0/",
+ 0, 0, 0},
{"file://localhost/path?query#frag",
"foo#another",
"file:///foo#another",
diff --git a/tests/libtest/lib1564.c b/tests/libtest/lib1564.c
index 13ac5b01e..1fe550ac4 100644
--- a/tests/libtest/lib1564.c
+++ b/tests/libtest/lib1564.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1565.c b/tests/libtest/lib1565.c
index b2fa40aaa..832b2ef89 100644
--- a/tests/libtest/lib1565.c
+++ b/tests/libtest/lib1565.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1567.c b/tests/libtest/lib1567.c
index f9e2f5c1a..c806cee0a 100644
--- a/tests/libtest/lib1567.c
+++ b/tests/libtest/lib1567.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1591.c b/tests/libtest/lib1591.c
index cc1c5b228..6dbafb25f 100644
--- a/tests/libtest/lib1591.c
+++ b/tests/libtest/lib1591.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1592.c b/tests/libtest/lib1592.c
index 5e6bf04eb..808aff6e1 100644
--- a/tests/libtest/lib1592.c
+++ b/tests/libtest/lib1592.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -43,7 +43,8 @@ int test(char *URL)
int stillRunning;
CURLM *multiHandle = NULL;
CURL *curl = NULL;
- CURLMcode res = CURLM_OK;
+ CURLcode res = CURLE_OK;
+ CURLMcode mres;
int timeout;
global_init(CURL_GLOBAL_ALL);
@@ -97,10 +98,11 @@ int test(char *URL)
/* Start measuring how long it takes to remove the handle. */
fprintf(stderr, "curl_multi_remove_handle()...\n");
start_test_timing();
- res = curl_multi_remove_handle(multiHandle, curl);
- if(res) {
+ mres = curl_multi_remove_handle(multiHandle, curl);
+ if(mres) {
fprintf(stderr, "curl_multi_remove_handle() failed, "
"with code %d\n", (int)res);
+ res = TEST_ERR_MULTI;
goto test_cleanup;
}
fprintf(stderr, "curl_multi_remove_handle() succeeded\n");
diff --git a/tests/libtest/lib1593.c b/tests/libtest/lib1593.c
index 5408c724a..e3b838e47 100644
--- a/tests/libtest/lib1593.c
+++ b/tests/libtest/lib1593.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1594.c b/tests/libtest/lib1594.c
index a76971590..4385c6044 100644
--- a/tests/libtest/lib1594.c
+++ b/tests/libtest/lib1594.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1900.c b/tests/libtest/lib1900.c
index fd7e5bc62..0b5209a0d 100644
--- a/tests/libtest/lib1900.c
+++ b/tests/libtest/lib1900.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1905.c b/tests/libtest/lib1905.c
index 7556d45e7..ab8e25425 100644
--- a/tests/libtest/lib1905.c
+++ b/tests/libtest/lib1905.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1906.c b/tests/libtest/lib1906.c
index 6c7a4bf6e..fdcc86d48 100644
--- a/tests/libtest/lib1906.c
+++ b/tests/libtest/lib1906.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1907.c b/tests/libtest/lib1907.c
index 2d9465aee..c4f8ff07c 100644
--- a/tests/libtest/lib1907.c
+++ b/tests/libtest/lib1907.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1908.c b/tests/libtest/lib1908.c
index bacbc9710..81267ac66 100644
--- a/tests/libtest/lib1908.c
+++ b/tests/libtest/lib1908.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -39,7 +39,22 @@ int test(char *URL)
curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L);
curl_easy_setopt(hnd, CURLOPT_ALTSVC, "log/altsvc-1908");
ret = curl_easy_perform(hnd);
+
+ if(!ret) {
+ /* make a copy and check that this also has alt-svc activated */
+ CURL *also = curl_easy_duphandle(hnd);
+ if(also) {
+ ret = curl_easy_perform(also);
+ /* we close the second handle first, which makes it store the alt-svc
+ file only to get overwritten when the next handle is closed! */
+ curl_easy_cleanup(also);
+ }
+ }
+
curl_easy_reset(hnd);
+
+ /* using the same file name for the alt-svc cache, this clobbers the
+ content just written from the 'also' handle */
curl_easy_cleanup(hnd);
}
curl_global_cleanup();
diff --git a/tests/libtest/lib1910.c b/tests/libtest/lib1910.c
index 1e25db5a4..7f2e29917 100644
--- a/tests/libtest/lib1910.c
+++ b/tests/libtest/lib1910.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib1911.c b/tests/libtest/lib1911.c
new file mode 100644
index 000000000..6d79bd898
--- /dev/null
+++ b/tests/libtest/lib1911.c
@@ -0,0 +1,89 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+/* The maximum string length limit (CURL_MAX_INPUT_LENGTH) is an internal
+ define not publicly exposed so we set our own */
+#define MAX_INPUT_LENGTH 8000000
+
+static char buffer[MAX_INPUT_LENGTH + 2];
+
+int test(char *URL)
+{
+ const struct curl_easyoption *o;
+ CURL *easy;
+ int error = 0;
+ (void)URL;
+
+ curl_global_init(CURL_GLOBAL_ALL);
+ easy = curl_easy_init();
+ if(!easy)
+ return 1;
+
+ /* make it a zero terminated C string with just As */
+ memset(buffer, 'A', MAX_INPUT_LENGTH + 1);
+ buffer[MAX_INPUT_LENGTH + 1] = 0;
+
+ printf("string length: %d\n", (int)strlen(buffer));
+
+ for(o = curl_easy_option_next(NULL);
+ o;
+ o = curl_easy_option_next(o)) {
+ if(o->type == CURLOT_STRING) {
+ CURLcode result;
+ /*
+ * Whitelist string options that are safe for abuse
+ */
+ switch(o->id) {
+ case CURLOPT_PROXY_TLSAUTH_TYPE:
+ case CURLOPT_TLSAUTH_TYPE:
+ continue;
+ default:
+ /* check this */
+ break;
+ }
+
+ /* This is a string. Make sure that passing in a string longer
+ CURL_MAX_INPUT_LENGTH returns an error */
+ result = curl_easy_setopt(easy, o->id, buffer);
+ switch(result) {
+ case CURLE_BAD_FUNCTION_ARGUMENT: /* the most normal */
+ case CURLE_UNKNOWN_OPTION: /* left out from the build */
+ case CURLE_NOT_BUILT_IN: /* not supported */
+ break;
+ default:
+ /* all other return codes are unexpected */
+ fprintf(stderr, "curl_easy_setopt(%s...) returned %d\n",
+ o->name, (int)result);
+ error++;
+ break;
+ }
+ }
+ }
+ curl_easy_cleanup(easy);
+ curl_global_cleanup();
+ return error;
+}
diff --git a/tests/libtest/lib1912.c b/tests/libtest/lib1912.c
new file mode 100644
index 000000000..32e5a3093
--- /dev/null
+++ b/tests/libtest/lib1912.c
@@ -0,0 +1,80 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define print_err(name, exp) \
+ fprintf(stderr, "Type mismatch for CURLOPT_%s (expected %s)\n", name, exp);
+
+int test(char *URL)
+{
+/* Only test if GCC typechecking is available */
+ int error = 0;
+#ifdef CURLINC_TYPECHECK_GCC_H
+ const struct curl_easyoption *o;
+ for(o = curl_easy_option_next(NULL);
+ o;
+ o = curl_easy_option_next(o)) {
+ /* Test for mismatch OR missing typecheck macros */
+ if(curlcheck_long_option(o->id) !=
+ (o->type == CURLOT_LONG || o->type == CURLOT_VALUES)) {
+ print_err(o->name, "CURLOT_LONG or CURLOT_VALUES");
+ error++;
+ }
+ if(curlcheck_off_t_option(o->id) != (o->type == CURLOT_OFF_T)) {
+ print_err(o->name, "CURLOT_OFF_T");
+ error++;
+ }
+ if(curlcheck_string_option(o->id) != (o->type == CURLOT_STRING)) {
+ print_err(o->name, "CURLOT_STRING");
+ error++;
+ }
+ if(curlcheck_slist_option(o->id) != (o->type == CURLOT_SLIST)) {
+ print_err(o->name, "CURLOT_SLIST");
+ error++;
+ }
+ if(curlcheck_cb_data_option(o->id) != (o->type == CURLOT_CBPTR)) {
+ print_err(o->name, "CURLOT_CBPTR");
+ error++;
+ }
+ /* From here: only test that the type matches if macro is known */
+ if(curlcheck_write_cb_option(o->id) && (o->type != CURLOT_FUNCTION)) {
+ print_err(o->name, "CURLOT_FUNCTION");
+ error++;
+ }
+ if(curlcheck_conv_cb_option(o->id) && (o->type != CURLOT_FUNCTION)) {
+ print_err(o->name, "CURLOT_FUNCTION");
+ error++;
+ }
+ if(curlcheck_postfields_option(o->id) && (o->type != CURLOT_OBJECT)) {
+ print_err(o->name, "CURLOT_OBJECT");
+ error++;
+ }
+ /* Todo: no gcc typecheck for CURLOPTTYPE_BLOB types? */
+ }
+#endif
+ (void)URL;
+ return error;
+}
diff --git a/tests/libtest/lib1913.c b/tests/libtest/lib1913.c
new file mode 100644
index 000000000..043a5329d
--- /dev/null
+++ b/tests/libtest/lib1913.c
@@ -0,0 +1,48 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+int test(char *URL)
+{
+ CURLcode ret = CURLE_OK;
+ CURL *hnd;
+ start_test_timing();
+
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ hnd = curl_easy_init();
+ if(hnd) {
+ curl_easy_setopt(hnd, CURLOPT_URL, URL);
+ curl_easy_setopt(hnd, CURLOPT_NOBODY, 1L);
+ if(libtest_arg2)
+ /* test1914 sets this extra arg */
+ curl_easy_setopt(hnd, CURLOPT_FILETIME, 1L);
+ ret = curl_easy_perform(hnd);
+ curl_easy_cleanup(hnd);
+ }
+ curl_global_cleanup();
+ return (int)ret;
+}
diff --git a/tests/libtest/lib1915.c b/tests/libtest/lib1915.c
new file mode 100644
index 000000000..4e632d3ab
--- /dev/null
+++ b/tests/libtest/lib1915.c
@@ -0,0 +1,95 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+static const char *preload_hosts[] = {
+ "1.example.com",
+ "2.example.com",
+ "3.example.com",
+ "4.example.com",
+ NULL /* end of list marker */
+};
+
+struct state {
+ int index;
+};
+
+/* "read" is from the point of the library, it wants data from us */
+static CURLSTScode hstsread(CURL *easy, struct curl_hstsentry *e,
+ void *userp)
+{
+ const char *host;
+ struct state *s = (struct state *)userp;
+ (void)easy;
+ host = preload_hosts[s->index++];
+
+ if(host && (strlen(host) < e->namelen)) {
+ strcpy(e->name, host);
+ e->includeSubDomains = FALSE;
+ strcpy(e->expire, "20300320 01:02:03"); /* curl turns 32 that day */
+ fprintf(stderr, "add '%s'\n", host);
+ }
+ else
+ return CURLSTS_DONE;
+ return CURLSTS_OK;
+}
+
+/* check that we get the hosts back in the save */
+static CURLSTScode hstswrite(CURL *easy, struct curl_hstsentry *e,
+ struct curl_index *i, void *userp)
+{
+ (void)easy;
+ (void)userp;
+ printf("[%zu/%zu] %s %s\n", i->index, i->total, e->name, e->expire);
+ return CURLSTS_OK;
+}
+
+/*
+ * Read/write HSTS cache entries via callback.
+ */
+
+int test(char *URL)
+{
+ CURLcode ret = CURLE_OK;
+ CURL *hnd;
+ struct state st = {0};
+
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ hnd = curl_easy_init();
+ if(hnd) {
+ curl_easy_setopt(hnd, CURLOPT_URL, URL);
+ curl_easy_setopt(hnd, CURLOPT_HSTSREADFUNCTION, hstsread);
+ curl_easy_setopt(hnd, CURLOPT_HSTSREADDATA, &st);
+ curl_easy_setopt(hnd, CURLOPT_HSTSWRITEFUNCTION, hstswrite);
+ curl_easy_setopt(hnd, CURLOPT_HSTSWRITEDATA, &st);
+ curl_easy_setopt(hnd, CURLOPT_HSTS_CTRL, CURLHSTS_ENABLE);
+ ret = curl_easy_perform(hnd);
+ curl_easy_cleanup(hnd);
+ }
+ curl_global_cleanup();
+ return (int)ret;
+}
diff --git a/tests/libtest/lib3010.c b/tests/libtest/lib3010.c
index 9c24b2f52..a52536d77 100644
--- a/tests/libtest/lib3010.c
+++ b/tests/libtest/lib3010.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib500.c b/tests/libtest/lib500.c
index 96dde3279..d3b4b60f7 100644
--- a/tests/libtest/lib500.c
+++ b/tests/libtest/lib500.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib501.c b/tests/libtest/lib501.c
index 95ffc0ae0..798ff61a2 100644
--- a/tests/libtest/lib501.c
+++ b/tests/libtest/lib501.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib502.c b/tests/libtest/lib502.c
index bfd45919b..e62b260b0 100644
--- a/tests/libtest/lib502.c
+++ b/tests/libtest/lib502.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib503.c b/tests/libtest/lib503.c
index a1c851fb3..4cb930cf8 100644
--- a/tests/libtest/lib503.c
+++ b/tests/libtest/lib503.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib504.c b/tests/libtest/lib504.c
index 9843393d9..efac42cec 100644
--- a/tests/libtest/lib504.c
+++ b/tests/libtest/lib504.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib505.c b/tests/libtest/lib505.c
index cc7463bde..6a101d728 100644
--- a/tests/libtest/lib505.c
+++ b/tests/libtest/lib505.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -71,7 +71,7 @@ int test(char *URL)
return TEST_ERR_MAJOR_BAD;
}
- if(! file_info.st_size) {
+ if(!file_info.st_size) {
fprintf(stderr, "ERROR: file %s has zero size!\n", libtest_arg2);
fclose(hd_src);
return TEST_ERR_MAJOR_BAD;
diff --git a/tests/libtest/lib506.c b/tests/libtest/lib506.c
index e0325ee00..559e7315d 100644
--- a/tests/libtest/lib506.c
+++ b/tests/libtest/lib506.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib507.c b/tests/libtest/lib507.c
index 9cd47ccd5..25b4e6e17 100644
--- a/tests/libtest/lib507.c
+++ b/tests/libtest/lib507.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib508.c b/tests/libtest/lib508.c
index 30705e46a..424ef50d3 100644
--- a/tests/libtest/lib508.c
+++ b/tests/libtest/lib508.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib509.c b/tests/libtest/lib509.c
index 1fb2d3445..20cadda77 100644
--- a/tests/libtest/lib509.c
+++ b/tests/libtest/lib509.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib510.c b/tests/libtest/lib510.c
index 4d568df44..0cd85d433 100644
--- a/tests/libtest/lib510.c
+++ b/tests/libtest/lib510.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib511.c b/tests/libtest/lib511.c
index 2467bf0b0..55d8fd254 100644
--- a/tests/libtest/lib511.c
+++ b/tests/libtest/lib511.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib512.c b/tests/libtest/lib512.c
index 84e2a9740..7b2af615a 100644
--- a/tests/libtest/lib512.c
+++ b/tests/libtest/lib512.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib513.c b/tests/libtest/lib513.c
index c6a98cca2..73bac3f31 100644
--- a/tests/libtest/lib513.c
+++ b/tests/libtest/lib513.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib514.c b/tests/libtest/lib514.c
index 702058b19..a1c58f77b 100644
--- a/tests/libtest/lib514.c
+++ b/tests/libtest/lib514.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib515.c b/tests/libtest/lib515.c
index 9f29d43c9..ae30d5ecb 100644
--- a/tests/libtest/lib515.c
+++ b/tests/libtest/lib515.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib516.c b/tests/libtest/lib516.c
index 6d83e218c..e54c54166 100644
--- a/tests/libtest/lib516.c
+++ b/tests/libtest/lib516.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib517.c b/tests/libtest/lib517.c
index 2f7d9a011..0f4b128b2 100644
--- a/tests/libtest/lib517.c
+++ b/tests/libtest/lib517.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib518.c b/tests/libtest/lib518.c
index 1a3091fcc..697aa8892 100644
--- a/tests/libtest/lib518.c
+++ b/tests/libtest/lib518.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib519.c b/tests/libtest/lib519.c
index f6b367922..8ed8d5c93 100644
--- a/tests/libtest/lib519.c
+++ b/tests/libtest/lib519.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib520.c b/tests/libtest/lib520.c
index 72b0875ed..bf26ec5b7 100644
--- a/tests/libtest/lib520.c
+++ b/tests/libtest/lib520.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib521.c b/tests/libtest/lib521.c
index 32819113e..43156b2d4 100644
--- a/tests/libtest/lib521.c
+++ b/tests/libtest/lib521.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib523.c b/tests/libtest/lib523.c
index 1708e1419..441fcec15 100644
--- a/tests/libtest/lib523.c
+++ b/tests/libtest/lib523.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib524.c b/tests/libtest/lib524.c
index fe195fd5e..bb7440210 100644
--- a/tests/libtest/lib524.c
+++ b/tests/libtest/lib524.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib525.c b/tests/libtest/lib525.c
index c179960c1..0826de3f1 100644
--- a/tests/libtest/lib525.c
+++ b/tests/libtest/lib525.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib526.c b/tests/libtest/lib526.c
index 42eb7cb18..a015699c5 100644
--- a/tests/libtest/lib526.c
+++ b/tests/libtest/lib526.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib530.c b/tests/libtest/lib530.c
index 8581303ae..c120d955a 100644
--- a/tests/libtest/lib530.c
+++ b/tests/libtest/lib530.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib533.c b/tests/libtest/lib533.c
index 7dd0fb59c..c6c014a95 100644
--- a/tests/libtest/lib533.c
+++ b/tests/libtest/lib533.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2011, 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib537.c b/tests/libtest/lib537.c
index e8fb16a49..a590786cb 100644
--- a/tests/libtest/lib537.c
+++ b/tests/libtest/lib537.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib539.c b/tests/libtest/lib539.c
index 7c03dd2fd..cd65e587e 100644
--- a/tests/libtest/lib539.c
+++ b/tests/libtest/lib539.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib540.c b/tests/libtest/lib540.c
index a52d8c501..94ee58e4b 100644
--- a/tests/libtest/lib540.c
+++ b/tests/libtest/lib540.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib541.c b/tests/libtest/lib541.c
index bcbaa481c..81939aacd 100644
--- a/tests/libtest/lib541.c
+++ b/tests/libtest/lib541.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -63,7 +63,7 @@ int test(char *URL)
return TEST_ERR_MAJOR_BAD;
}
- if(! file_info.st_size) {
+ if(!file_info.st_size) {
fprintf(stderr, "ERROR: file %s has zero size!\n", libtest_arg2);
fclose(hd_src);
return TEST_ERR_MAJOR_BAD;
diff --git a/tests/libtest/lib542.c b/tests/libtest/lib542.c
index 4016874e1..9b54bcfbe 100644
--- a/tests/libtest/lib542.c
+++ b/tests/libtest/lib542.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib543.c b/tests/libtest/lib543.c
index c494d3d83..10270dfa9 100644
--- a/tests/libtest/lib543.c
+++ b/tests/libtest/lib543.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib544.c b/tests/libtest/lib544.c
index 60de7fc67..5b5711223 100644
--- a/tests/libtest/lib544.c
+++ b/tests/libtest/lib544.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib547.c b/tests/libtest/lib547.c
index 1416f895c..11e62d583 100644
--- a/tests/libtest/lib547.c
+++ b/tests/libtest/lib547.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib549.c b/tests/libtest/lib549.c
index 886625427..f593f2def 100644
--- a/tests/libtest/lib549.c
+++ b/tests/libtest/lib549.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib552.c b/tests/libtest/lib552.c
index 7a960417d..75779eefe 100644
--- a/tests/libtest/lib552.c
+++ b/tests/libtest/lib552.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib553.c b/tests/libtest/lib553.c
index 015bf29ac..d52ce082a 100644
--- a/tests/libtest/lib553.c
+++ b/tests/libtest/lib553.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib554.c b/tests/libtest/lib554.c
index cc21d245b..18e8950c2 100644
--- a/tests/libtest/lib554.c
+++ b/tests/libtest/lib554.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib555.c b/tests/libtest/lib555.c
index 42c89d8c9..392ae7dcd 100644
--- a/tests/libtest/lib555.c
+++ b/tests/libtest/lib555.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib556.c b/tests/libtest/lib556.c
index 0595000ce..f01fa71d4 100644
--- a/tests/libtest/lib556.c
+++ b/tests/libtest/lib556.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -96,7 +96,7 @@ int test(char *URL)
}
if(iolen != 0)
- res = TEST_ERR_FAILURE;
+ res = (CURLcode)TEST_ERR_FAILURE;
}
test_cleanup:
diff --git a/tests/libtest/lib557.c b/tests/libtest/lib557.c
index b34a0c2f0..00fbca38c 100644
--- a/tests/libtest/lib557.c
+++ b/tests/libtest/lib557.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib558.c b/tests/libtest/lib558.c
index 52340d720..1134a4d72 100644
--- a/tests/libtest/lib558.c
+++ b/tests/libtest/lib558.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib559.c b/tests/libtest/lib559.c
index 2203cff3b..bcc9a8fae 100644
--- a/tests/libtest/lib559.c
+++ b/tests/libtest/lib559.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib560.c b/tests/libtest/lib560.c
index 56ee2001e..74a25cd5f 100644
--- a/tests/libtest/lib560.c
+++ b/tests/libtest/lib560.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib562.c b/tests/libtest/lib562.c
index 285b9f5d0..000fa302c 100644
--- a/tests/libtest/lib562.c
+++ b/tests/libtest/lib562.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib564.c b/tests/libtest/lib564.c
index f959f2043..9c2b27144 100644
--- a/tests/libtest/lib564.c
+++ b/tests/libtest/lib564.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2013, 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib566.c b/tests/libtest/lib566.c
index 04e3032ed..fdf17ed41 100644
--- a/tests/libtest/lib566.c
+++ b/tests/libtest/lib566.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib567.c b/tests/libtest/lib567.c
index f6af06191..a0ebead87 100644
--- a/tests/libtest/lib567.c
+++ b/tests/libtest/lib567.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib568.c b/tests/libtest/lib568.c
index 128e6d2eb..e74babed6 100644
--- a/tests/libtest/lib568.c
+++ b/tests/libtest/lib568.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib569.c b/tests/libtest/lib569.c
index 80116dad3..1fcfe9d50 100644
--- a/tests/libtest/lib569.c
+++ b/tests/libtest/lib569.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib570.c b/tests/libtest/lib570.c
index 016ed1098..5d2f5b5b5 100644
--- a/tests/libtest/lib570.c
+++ b/tests/libtest/lib570.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -101,8 +101,12 @@ int test(char *URL)
stream_uri = NULL;
res = curl_easy_perform(curl);
- if(res != CURLE_RTSP_SESSION_ERROR) {
+ if(res == CURLE_RTSP_SESSION_ERROR) {
+ res = 0;
+ }
+ else {
fprintf(stderr, "Failed to detect a Session ID mismatch");
+ res = 1;
}
test_cleanup:
diff --git a/tests/libtest/lib571.c b/tests/libtest/lib571.c
index 002617878..91c3e7d3d 100644
--- a/tests/libtest/lib571.c
+++ b/tests/libtest/lib571.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib572.c b/tests/libtest/lib572.c
index 0352fdb7f..dc7047848 100644
--- a/tests/libtest/lib572.c
+++ b/tests/libtest/lib572.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib573.c b/tests/libtest/lib573.c
index f512e2d3c..7126dfa73 100644
--- a/tests/libtest/lib573.c
+++ b/tests/libtest/lib573.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib574.c b/tests/libtest/lib574.c
index f4fb850ff..d27f1519c 100644
--- a/tests/libtest/lib574.c
+++ b/tests/libtest/lib574.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib575.c b/tests/libtest/lib575.c
index 6baa12229..f511835c5 100644
--- a/tests/libtest/lib575.c
+++ b/tests/libtest/lib575.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2011, 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib576.c b/tests/libtest/lib576.c
index f66825895..fa75e7813 100644
--- a/tests/libtest/lib576.c
+++ b/tests/libtest/lib576.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib578.c b/tests/libtest/lib578.c
index 1b4ee526c..ec3bc01e9 100644
--- a/tests/libtest/lib578.c
+++ b/tests/libtest/lib578.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib579.c b/tests/libtest/lib579.c
index 64ef16021..ef90944b0 100644
--- a/tests/libtest/lib579.c
+++ b/tests/libtest/lib579.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib582.c b/tests/libtest/lib582.c
index 96841052b..caaefe0bf 100644
--- a/tests/libtest/lib582.c
+++ b/tests/libtest/lib582.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib583.c b/tests/libtest/lib583.c
index 86dd8b55a..0ff0c09dc 100644
--- a/tests/libtest/lib583.c
+++ b/tests/libtest/lib583.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -21,7 +21,7 @@
***************************************************************************/
/*
* This test case is based on the sample code provided by Saqib Ali
- * https://curl.haxx.se/mail/lib-2011-03/0066.html
+ * https://curl.se/mail/lib-2011-03/0066.html
*/
#include "test.h"
@@ -35,7 +35,8 @@ int test(char *URL)
int stillRunning;
CURLM *multiHandle = NULL;
CURL *curl = NULL;
- CURLMcode res = CURLM_OK;
+ CURLcode res = CURLE_OK;
+ CURLMcode mres;
global_init(CURL_GLOBAL_ALL);
@@ -65,10 +66,12 @@ int test(char *URL)
fprintf(stderr, "curl_multi_perform() succeeded\n");
fprintf(stderr, "curl_multi_remove_handle()...\n");
- res = curl_multi_remove_handle(multiHandle, curl);
- if(res)
+ mres = curl_multi_remove_handle(multiHandle, curl);
+ if(mres) {
fprintf(stderr, "curl_multi_remove_handle() failed, "
- "with code %d\n", (int)res);
+ "with code %d\n", (int)mres);
+ res = TEST_ERR_MULTI;
+ }
else
fprintf(stderr, "curl_multi_remove_handle() succeeded\n");
diff --git a/tests/libtest/lib586.c b/tests/libtest/lib586.c
index 3b77ef7eb..da63e7cb8 100644
--- a/tests/libtest/lib586.c
+++ b/tests/libtest/lib586.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib589.c b/tests/libtest/lib589.c
index 667459d0d..43b1aee01 100644
--- a/tests/libtest/lib589.c
+++ b/tests/libtest/lib589.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib590.c b/tests/libtest/lib590.c
index ca54e3070..4414ae7cd 100644
--- a/tests/libtest/lib590.c
+++ b/tests/libtest/lib590.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -23,7 +23,7 @@
/*
Based on a bug report recipe by Rene Bernhardt in
- https://curl.haxx.se/mail/lib-2011-10/0323.html
+ https://curl.se/mail/lib-2011-10/0323.html
It is reproducible by the following steps:
diff --git a/tests/libtest/lib591.c b/tests/libtest/lib591.c
index 9c5edd89c..318cc071e 100644
--- a/tests/libtest/lib591.c
+++ b/tests/libtest/lib591.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib597.c b/tests/libtest/lib597.c
index e34505cd2..3f9964723 100644
--- a/tests/libtest/lib597.c
+++ b/tests/libtest/lib597.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib598.c b/tests/libtest/lib598.c
index 002f041ec..8c1c3e04c 100644
--- a/tests/libtest/lib598.c
+++ b/tests/libtest/lib598.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib599.c b/tests/libtest/lib599.c
index 0e05977b5..8202919f7 100644
--- a/tests/libtest/lib599.c
+++ b/tests/libtest/lib599.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib643.c b/tests/libtest/lib643.c
index 5af0f4a14..3c75108e2 100644
--- a/tests/libtest/lib643.c
+++ b/tests/libtest/lib643.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib650.c b/tests/libtest/lib650.c
index 79d60b624..f0e6b81cd 100644
--- a/tests/libtest/lib650.c
+++ b/tests/libtest/lib650.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib651.c b/tests/libtest/lib651.c
index 777f6f59b..489331a29 100644
--- a/tests/libtest/lib651.c
+++ b/tests/libtest/lib651.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib652.c b/tests/libtest/lib652.c
index 3d247d27b..4e23dfa33 100644
--- a/tests/libtest/lib652.c
+++ b/tests/libtest/lib652.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib653.c b/tests/libtest/lib653.c
index 6d78ee0f4..878ed7725 100644
--- a/tests/libtest/lib653.c
+++ b/tests/libtest/lib653.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib654.c b/tests/libtest/lib654.c
index f9c8b9118..e7e957c46 100644
--- a/tests/libtest/lib654.c
+++ b/tests/libtest/lib654.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib655.c b/tests/libtest/lib655.c
index 8777b99ed..751eccdf8 100644
--- a/tests/libtest/lib655.c
+++ b/tests/libtest/lib655.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib658.c b/tests/libtest/lib658.c
index 98e0db4b4..85738d0c1 100644
--- a/tests/libtest/lib658.c
+++ b/tests/libtest/lib658.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2011, 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib659.c b/tests/libtest/lib659.c
index b37e8e940..d06986c39 100644
--- a/tests/libtest/lib659.c
+++ b/tests/libtest/lib659.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib661.c b/tests/libtest/lib661.c
index a4f2c8e5c..16eaa0c11 100644
--- a/tests/libtest/lib661.c
+++ b/tests/libtest/lib661.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib666.c b/tests/libtest/lib666.c
index c75936eeb..3c9cfe0a6 100644
--- a/tests/libtest/lib666.c
+++ b/tests/libtest/lib666.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib667.c b/tests/libtest/lib667.c
index 8bf7be43f..d30b9534e 100644
--- a/tests/libtest/lib667.c
+++ b/tests/libtest/lib667.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib668.c b/tests/libtest/lib668.c
index c0b608a0a..bd8ae3b3a 100644
--- a/tests/libtest/lib668.c
+++ b/tests/libtest/lib668.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib670.c b/tests/libtest/lib670.c
index aecb1c01f..e00a13923 100644
--- a/tests/libtest/lib670.c
+++ b/tests/libtest/lib670.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/lib674.c b/tests/libtest/lib674.c
index 828e52cd5..336cf77f5 100644
--- a/tests/libtest/lib674.c
+++ b/tests/libtest/lib674.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/libauthretry.c b/tests/libtest/libauthretry.c
index cfad6f3e9..a19801080 100644
--- a/tests/libtest/libauthretry.c
+++ b/tests/libtest/libauthretry.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/libntlmconnect.c b/tests/libtest/libntlmconnect.c
index 426f6f245..11da56f41 100644
--- a/tests/libtest/libntlmconnect.c
+++ b/tests/libtest/libntlmconnect.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/mk-lib1521.pl b/tests/libtest/mk-lib1521.pl
index 14b222098..ba60862cd 100755
--- a/tests/libtest/mk-lib1521.pl
+++ b/tests/libtest/mk-lib1521.pl
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -42,7 +42,7 @@ print <<HEADER
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -133,6 +133,8 @@ static curl_chunk_end_callback chunk_end_cb;
static curl_fnmatch_callback fnmatch_cb;
static curl_closesocket_callback closesocketcb;
static curl_xferinfo_callback xferinfocb;
+static curl_hstsread_callback hstsreadcb;
+static curl_hstswrite_callback hstswritecb;
static curl_resolver_start_callback resolver_start_cb;
int test(char *URL)
@@ -184,13 +186,15 @@ while(<STDIN>) {
print "${pref} \"string\");\n$check";
print "${pref} NULL);\n$check";
}
- elsif($type eq "CURLOPTTYPE_LONG") {
+ elsif(($type eq "CURLOPTTYPE_LONG") ||
+ ($type eq "CURLOPTTYPE_VALUES")) {
print "${pref} 0L);\n$check";
print "${pref} 22L);\n$check";
print "${pref} LO);\n$check";
print "${pref} HI);\n$check";
}
- elsif($type eq "CURLOPTTYPE_OBJECTPOINT") {
+ elsif(($type eq "CURLOPTTYPE_OBJECTPOINT") ||
+ ($type eq "CURLOPTTYPE_CBPOINT")) {
if($name =~ /DEPENDS/) {
print "${pref} dep);\n$check";
}
@@ -244,8 +248,8 @@ while(<STDIN>) {
print "${pref} &blob);\n$check";
}
else {
- print STDERR "\n---- $type\n";
- exit; # exit to make this noticed!
+ print STDERR "\nUnknown type: $type\n";
+ exit 22; # exit to make this noticed!
}
}
elsif($_ =~ /^ CURLINFO_NONE/) {
@@ -295,7 +299,7 @@ while(<STDIN>) {
print <<FOOTER
- curl_easy_setopt(curl, 1, 0);
+ curl_easy_setopt(curl, (CURLoption)1, 0);
res = CURLE_OK;
test_cleanup:
curl_easy_cleanup(curl);
diff --git a/tests/libtest/notexists.pl b/tests/libtest/notexists.pl
index ed081414c..8f09598e8 100755
--- a/tests/libtest/notexists.pl
+++ b/tests/libtest/notexists.pl
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/sethostname.c b/tests/libtest/sethostname.c
index 6929793dc..1a1fdfd67 100644
--- a/tests/libtest/sethostname.c
+++ b/tests/libtest/sethostname.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/sethostname.h b/tests/libtest/sethostname.h
index 64624e846..7b2f2ed13 100644
--- a/tests/libtest/sethostname.h
+++ b/tests/libtest/sethostname.h
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -22,7 +22,7 @@
#ifdef CURL_STATICLIB
# define LIBHOSTNAME_EXTERN
-#elif defined(WIN32) || defined(__SYMBIAN32__)
+#elif defined(WIN32)
# define LIBHOSTNAME_EXTERN __declspec(dllexport)
#elif defined(CURL_HIDDEN_SYMBOLS)
# define LIBHOSTNAME_EXTERN CURL_EXTERN_SYMBOL
diff --git a/tests/libtest/stub_gssapi.c b/tests/libtest/stub_gssapi.c
index 873e263dc..6cc1697cd 100644
--- a/tests/libtest/stub_gssapi.c
+++ b/tests/libtest/stub_gssapi.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2017-2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2017 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/stub_gssapi.h b/tests/libtest/stub_gssapi.h
index aab3449b1..5a89102d0 100644
--- a/tests/libtest/stub_gssapi.h
+++ b/tests/libtest/stub_gssapi.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/test.h b/tests/libtest/test.h
index 8aba00f46..ec03a14a9 100644
--- a/tests/libtest/test.h
+++ b/tests/libtest/test.h
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -86,18 +86,18 @@ extern int unitfail;
** For portability reasons TEST_ERR_* values should be less than 127.
*/
-#define TEST_ERR_MAJOR_BAD 126
-#define TEST_ERR_RUNS_FOREVER 125
-#define TEST_ERR_EASY_INIT 124
-#define TEST_ERR_MULTI_INIT 123
-#define TEST_ERR_NUM_HANDLES 122
-#define TEST_ERR_SELECT 121
-#define TEST_ERR_SUCCESS 120
-#define TEST_ERR_FAILURE 119
-#define TEST_ERR_USAGE 118
-#define TEST_ERR_FOPEN 117
-#define TEST_ERR_FSTAT 116
-#define TEST_ERR_BAD_TIMEOUT 115
+#define TEST_ERR_MAJOR_BAD (CURLcode) 126
+#define TEST_ERR_RUNS_FOREVER (CURLcode) 125
+#define TEST_ERR_EASY_INIT (CURLcode) 124
+#define TEST_ERR_MULTI (CURLcode) 123
+#define TEST_ERR_NUM_HANDLES (CURLcode) 122
+#define TEST_ERR_SELECT (CURLcode) 121
+#define TEST_ERR_SUCCESS (CURLcode) 120
+#define TEST_ERR_FAILURE (CURLcode) 119
+#define TEST_ERR_USAGE (CURLcode) 118
+#define TEST_ERR_FOPEN (CURLcode) 117
+#define TEST_ERR_FSTAT (CURLcode) 116
+#define TEST_ERR_BAD_TIMEOUT (CURLcode) 115
/*
** Macros for test source code readability/maintainability.
@@ -154,7 +154,7 @@ extern int unitfail;
#define exe_multi_init(A,Y,Z) do { \
if(((A) = curl_multi_init()) == NULL) { \
fprintf(stderr, "%s:%d curl_multi_init() failed\n", (Y), (Z)); \
- res = TEST_ERR_MULTI_INIT; \
+ res = TEST_ERR_MULTI; \
} \
} while(0)
@@ -178,7 +178,7 @@ extern int unitfail;
fprintf(stderr, "%s:%d curl_easy_setopt() failed, " \
"with code %d (%s)\n", \
(Y), (Z), (int)ec, curl_easy_strerror(ec)); \
- res = (int)ec; \
+ res = ec; \
} \
} while(0)
@@ -202,7 +202,7 @@ extern int unitfail;
fprintf(stderr, "%s:%d curl_multi_setopt() failed, " \
"with code %d (%s)\n", \
(Y), (Z), (int)ec, curl_multi_strerror(ec)); \
- res = (int)ec; \
+ res = TEST_ERR_MULTI; \
} \
} while(0)
@@ -226,7 +226,7 @@ extern int unitfail;
fprintf(stderr, "%s:%d curl_multi_add_handle() failed, " \
"with code %d (%s)\n", \
(Y), (Z), (int)ec, curl_multi_strerror(ec)); \
- res = (int)ec; \
+ res = TEST_ERR_MULTI; \
} \
} while(0)
@@ -250,7 +250,7 @@ extern int unitfail;
fprintf(stderr, "%s:%d curl_multi_remove_handle() failed, " \
"with code %d (%s)\n", \
(Y), (Z), (int)ec, curl_multi_strerror(ec)); \
- res = (int)ec; \
+ res = TEST_ERR_MULTI; \
} \
} while(0)
@@ -275,7 +275,7 @@ extern int unitfail;
fprintf(stderr, "%s:%d curl_multi_perform() failed, " \
"with code %d (%s)\n", \
(Y), (Z), (int)ec, curl_multi_strerror(ec)); \
- res = (int)ec; \
+ res = TEST_ERR_MULTI; \
} \
else if(*((B)) < 0) { \
fprintf(stderr, "%s:%d curl_multi_perform() succeeded, " \
@@ -305,7 +305,7 @@ extern int unitfail;
fprintf(stderr, "%s:%d curl_multi_fdset() failed, " \
"with code %d (%s)\n", \
(Y), (Z), (int)ec, curl_multi_strerror(ec)); \
- res = (int)ec; \
+ res = TEST_ERR_MULTI; \
} \
else if(*((E)) < -1) { \
fprintf(stderr, "%s:%d curl_multi_fdset() succeeded, " \
@@ -335,7 +335,7 @@ extern int unitfail;
fprintf(stderr, "%s:%d curl_multi_timeout() failed, " \
"with code %d (%s)\n", \
(Y), (Z), (int)ec, curl_multi_strerror(ec)); \
- res = (int)ec; \
+ res = TEST_ERR_BAD_TIMEOUT; \
} \
else if(*((B)) < -1L) { \
fprintf(stderr, "%s:%d curl_multi_timeout() succeeded, " \
@@ -365,7 +365,7 @@ extern int unitfail;
fprintf(stderr, "%s:%d curl_multi_poll() failed, " \
"with code %d (%s)\n", \
(Y), (Z), (int)ec, curl_multi_strerror(ec)); \
- res = (int)ec; \
+ res = TEST_ERR_MULTI; \
} \
else if(*((E)) < 0) { \
fprintf(stderr, "%s:%d curl_multi_poll() succeeded, " \
@@ -395,7 +395,7 @@ extern int unitfail;
fprintf(stderr, "%s:%d curl_multi_wakeup() failed, " \
"with code %d (%s)\n", \
(Y), (Z), (int)ec, curl_multi_strerror(ec)); \
- res = (int)ec; \
+ res = TEST_ERR_MULTI; \
} \
} while(0)
@@ -470,7 +470,7 @@ extern int unitfail;
fprintf(stderr, "%s:%d curl_global_init() failed, " \
"with code %d (%s)\n", \
(Y), (Z), (int)ec, curl_easy_strerror(ec)); \
- res = (int)ec; \
+ res = ec; \
} \
} while(0)
diff --git a/tests/libtest/test1013.pl b/tests/libtest/test1013.pl
index 70c74c04b..055ef957a 100755
--- a/tests/libtest/test1013.pl
+++ b/tests/libtest/test1013.pl
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/test1022.pl b/tests/libtest/test1022.pl
index 86b956bb4..19cd182b0 100755
--- a/tests/libtest/test1022.pl
+++ b/tests/libtest/test1022.pl
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/test307.pl b/tests/libtest/test307.pl
index c7e989f0c..b5da4ffaa 100755
--- a/tests/libtest/test307.pl
+++ b/tests/libtest/test307.pl
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/test610.pl b/tests/libtest/test610.pl
index c3df29bb7..a3ac8c6ea 100755
--- a/tests/libtest/test610.pl
+++ b/tests/libtest/test610.pl
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/test613.pl b/tests/libtest/test613.pl
index 8efc05ca0..368d7beb2 100755
--- a/tests/libtest/test613.pl
+++ b/tests/libtest/test613.pl
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/testtrace.c b/tests/libtest/testtrace.c
index 2718ef939..d17136548 100644
--- a/tests/libtest/testtrace.c
+++ b/tests/libtest/testtrace.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/testtrace.h b/tests/libtest/testtrace.h
index 54df28b1c..f715ef540 100644
--- a/tests/libtest/testtrace.h
+++ b/tests/libtest/testtrace.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/testutil.c b/tests/libtest/testutil.c
index 504b15324..c8779f2b2 100644
--- a/tests/libtest/testutil.c
+++ b/tests/libtest/testutil.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/libtest/testutil.h b/tests/libtest/testutil.h
index ccf84dff2..e766ad4a0 100644
--- a/tests/libtest/testutil.h
+++ b/tests/libtest/testutil.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/manpage-scan.pl.in b/tests/manpage-scan.pl.in
index 59d6ce817..ce0cc66d5 100755
--- a/tests/manpage-scan.pl.in
+++ b/tests/manpage-scan.pl.in
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/mem-include-scan.pl.in b/tests/mem-include-scan.pl.in
index a7ab544ed..d137e4fd1 100755
--- a/tests/mem-include-scan.pl.in
+++ b/tests/mem-include-scan.pl.in
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/memanalyze.pl.in b/tests/memanalyze.pl.in
index b16172d38..01915ebca 100755
--- a/tests/memanalyze.pl.in
+++ b/tests/memanalyze.pl.in
@@ -6,11 +6,11 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/negtelnetserver.py.in b/tests/negtelnetserver.py.in
index fbe3a5f63..afd48239d 100755
--- a/tests/negtelnetserver.py.in
+++ b/tests/negtelnetserver.py.in
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -23,10 +23,14 @@
from __future__ import (absolute_import, division, print_function,
unicode_literals)
+
import argparse
+import logging
import os
import sys
-import logging
+
+from util import ClosingFileHandler
+
if sys.version_info.major >= 3:
import socketserver
else:
@@ -313,7 +317,7 @@ def setup_logging(options):
# Write out to a logfile
if options.logfile:
- handler = logging.FileHandler(options.logfile, mode="w")
+ handler = ClosingFileHandler(options.logfile)
handler.setFormatter(formatter)
handler.setLevel(logging.DEBUG)
root_logger.addHandler(handler)
diff --git a/tests/nroff-scan.pl.in b/tests/nroff-scan.pl.in
index 8f4f2a24c..7c1d90e2b 100755
--- a/tests/nroff-scan.pl.in
+++ b/tests/nroff-scan.pl.in
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/objnames-test08.sh b/tests/objnames-test08.sh
deleted file mode 100755
index 0e4a252e2..000000000
--- a/tests/objnames-test08.sh
+++ /dev/null
@@ -1,217 +0,0 @@
-#!/bin/sh
-# ***************************************************************************
-# * _ _ ____ _
-# * Project ___| | | | _ \| |
-# * / __| | | | |_) | |
-# * | (__| |_| | _ <| |___
-# * \___|\___/|_| \_\_____|
-# *
-# * Copyright (C) 2013 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
-# *
-# * This software is licensed as described in the file COPYING, which
-# * you should have received as part of this distribution. The terms
-# * are also available at https://curl.haxx.se/docs/copyright.html.
-# *
-# * You may opt to use, copy, modify, merge, publish, distribute and/or sell
-# * copies of the Software, and permit persons to whom the Software is
-# * furnished to do so, under the terms of the COPYING file.
-# *
-# * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
-# * KIND, either express or implied.
-# *
-# ***************************************************************************
-
-#
-# This Bourne shell script file is used by test case 1222 to do
-# unit testing of curl_8char_object_name() shell function which
-# is defined in file objnames.inc and sourced by this file and
-# any other shell script that may use it.
-#
-
-#
-# argument validation
-#
-
-if test $# -eq 1; then
- :
-else
- echo "Usage: ${0} srcdir"
- exit 1
-fi
-
-if test -f "${1}/runtests.pl"; then
- :
-else
- echo "${0}: Wrong srcdir"
- exit 1
-fi
-
-srcdir=${1}
-
-if test -f "$srcdir/objnames.inc"; then
- :
-else
- echo "$0: Missing objnames.inc"
- exit 1
-fi
-
-#
-# Some variables
-#
-
-logdir=log
-tstnum=1222
-
-list_c=$logdir/${tstnum}_list_c
-list_obj=$logdir/${tstnum}_list_obj
-list_obj_c=$logdir/${tstnum}_list_obj_c
-list_obj_uniq=$logdir/${tstnum}_list_obj_uniq
-
-
-#
-# Source curl_8char_object_name() function definition
-#
-
-. $srcdir/objnames.inc
-
-#
-# Some curl_8char_object_name() unit tests
-#
-
-echo 'Testing curl_8char_object_name...'
-echo ""
-
-argstr=123__678__ABC__FGH__KLM__PQRSTUV
-expect=16AFKPQR
-outstr=`curl_8char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=123__678__ABC__FGH__KLM__PQ.S.UV
-expect=16AFKPQ
-outstr=`curl_8char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=123__678__ABC..FGH..KLM..PQRSTUV
-expect=16ABC
-outstr=`curl_8char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=123__678_.ABC._FGH__KLM__PQRSTUV
-expect=16
-outstr=`curl_8char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=123.567.90ABCDEFGHIJKLMNOPQRSTUV
-expect=123
-outstr=`curl_8char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=1234567.90A.CDEFGHIJKLMNOPQRSTUV
-expect=1234567
-outstr=`curl_8char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=1234567890.BCD.FGHIJKLMNOPQRSTUV
-expect=12345678
-outstr=`curl_8char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=12=45-78+0AB.DE.GHIJKLMNOPQRSTUV
-expect=1470AB
-outstr=`curl_8char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=1234567890ABCDEFGHIJKLMNOPQRSTUV
-expect=12345678
-outstr=`curl_8char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=123_567_90A_CDE_GHIJKLMNOPQRSTUV
-expect=159CGHIJ
-outstr=`curl_8char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=123_567_90A_CDEFGHIJKLMNOPQRSTUV
-expect=159CDEFG
-outstr=`curl_8char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=123_567_90ABCDEFGHIJKLMNOPQRSTUV
-expect=1590ABCD
-outstr=`curl_8char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=123_567890ABCDEFGHIJKLMNOPQRSTUV
-expect=1567890A
-outstr=`curl_8char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=1234567890ABCDEFGHIJKLMNOPQRSTUV
-expect=12345678
-outstr=`curl_8char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-#
-# Verify that generated object name is distinct for
-# all *.c source files in lib and src subdirectories.
-#
-
-ls $srcdir/../lib/*.c > $list_c
-ls $srcdir/../src/*.c >> $list_c
-
-rm -f $list_obj
-
-for c_fname in `cat $list_c`; do
- obj_name=`curl_8char_object_name $c_fname`
- echo "$obj_name" >> $list_obj
-done
-
-sort -u $list_obj > $list_obj_uniq
-
-cnt_c=`cat $list_c | wc -l`
-cnt_u=`cat $list_obj_uniq | wc -l`
-
-echo ""
-echo ""
-echo ""
-if test $cnt_c -eq $cnt_u; then
- echo "8-characters-or-less generated object names are unique."
- obj_name_clash="no"
-else
- echo "8-characters-or-less generated object names are clashing..."
- obj_name_clash="yes"
-fi
-
-if test $obj_name_clash = "yes"; then
- #
- # Show clashing object names and respective source file names
- #
- echo ""
- paste $list_obj $list_c | sort > $list_obj_c
- prev_match="no"
- prev_line="unknown"
- prev_obj_name="unknown"
- while read this_line; do
- obj_name=`echo "$this_line" | cut -f1`
- if test "x$obj_name" = "x$prev_obj_name"; then
- if test "x$prev_match" != "xyes"; then
- echo "$prev_line"
- echo "$this_line"
- prev_match="yes"
- else
- echo "$this_line"
- fi
- else
- prev_match="no"
- fi
- prev_line=$this_line
- prev_obj_name=$obj_name
- done < $list_obj_c
-fi
-
-rm -f $list_c
-rm -f $list_obj
-rm -f $list_obj_c
-rm -f $list_obj_uniq
-
-# end of objnames-test.sh
diff --git a/tests/objnames-test10.sh b/tests/objnames-test10.sh
deleted file mode 100755
index 3d101dcee..000000000
--- a/tests/objnames-test10.sh
+++ /dev/null
@@ -1,217 +0,0 @@
-#!/bin/sh
-# ***************************************************************************
-# * _ _ ____ _
-# * Project ___| | | | _ \| |
-# * / __| | | | |_) | |
-# * | (__| |_| | _ <| |___
-# * \___|\___/|_| \_\_____|
-# *
-# * Copyright (C) 2013 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
-# *
-# * This software is licensed as described in the file COPYING, which
-# * you should have received as part of this distribution. The terms
-# * are also available at https://curl.haxx.se/docs/copyright.html.
-# *
-# * You may opt to use, copy, modify, merge, publish, distribute and/or sell
-# * copies of the Software, and permit persons to whom the Software is
-# * furnished to do so, under the terms of the COPYING file.
-# *
-# * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
-# * KIND, either express or implied.
-# *
-# ***************************************************************************
-
-#
-# This Bourne shell script file is used by test case 1221 to do
-# unit testing of curl_10char_object_name() shell function which
-# is defined in file objnames.inc and sourced by this file and
-# any other shell script that may use it.
-#
-
-#
-# argument validation
-#
-
-if test $# -eq 1; then
- :
-else
- echo "Usage: ${0} srcdir"
- exit 1
-fi
-
-if test -f "${1}/runtests.pl"; then
- :
-else
- echo "${0}: Wrong srcdir"
- exit 1
-fi
-
-srcdir=${1}
-
-if test -f "$srcdir/objnames.inc"; then
- :
-else
- echo "$0: Missing objnames.inc"
- exit 1
-fi
-
-#
-# Some variables
-#
-
-logdir=log
-tstnum=1221
-
-list_c=$logdir/${tstnum}_list_c
-list_obj=$logdir/${tstnum}_list_obj
-list_obj_c=$logdir/${tstnum}_list_obj_c
-list_obj_uniq=$logdir/${tstnum}_list_obj_uniq
-
-
-#
-# Source curl_10char_object_name() function definition
-#
-
-. $srcdir/objnames.inc
-
-#
-# Some curl_10char_object_name() unit tests
-#
-
-echo 'Testing curl_10char_object_name...'
-echo ""
-
-argstr=123__678__ABC__FGH__KLM__PQRSTUV
-expect=16AFKPQRST
-outstr=`curl_10char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=123__678__ABC__FGH__KLM__PQ.S.UV
-expect=16AFKPQ
-outstr=`curl_10char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=123__678__ABC..FGH..KLM..PQRSTUV
-expect=16ABC
-outstr=`curl_10char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=123__678_.ABC._FGH__KLM__PQRSTUV
-expect=16
-outstr=`curl_10char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=123.567.90ABCDEFGHIJKLMNOPQRSTUV
-expect=123
-outstr=`curl_10char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=1234567.90A.CDEFGHIJKLMNOPQRSTUV
-expect=1234567
-outstr=`curl_10char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=1234567890.BCD.FGHIJKLMNOPQRSTUV
-expect=1234567890
-outstr=`curl_10char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=12=45-78+0AB.DE.GHIJKLMNOPQRSTUV
-expect=1470AB
-outstr=`curl_10char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=1234567890ABCDEFGHIJKLMNOPQRSTUV
-expect=1234567890
-outstr=`curl_10char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=123_567_90A_CDE_GHIJKLMNOPQRSTUV
-expect=159CGHIJKL
-outstr=`curl_10char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=123_567_90A_CDEFGHIJKLMNOPQRSTUV
-expect=159CDEFGHI
-outstr=`curl_10char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=123_567_90ABCDEFGHIJKLMNOPQRSTUV
-expect=1590ABCDEF
-outstr=`curl_10char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=123_567890ABCDEFGHIJKLMNOPQRSTUV
-expect=1567890ABC
-outstr=`curl_10char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-argstr=1234567890ABCDEFGHIJKLMNOPQRSTUV
-expect=1234567890
-outstr=`curl_10char_object_name $argstr`
-echo "result: $outstr expected: $expect input: $argstr"
-
-#
-# Verify that generated object name is distinct for
-# all *.c source files in lib and src subdirectories.
-#
-
-ls $srcdir/../lib/*.c > $list_c
-ls $srcdir/../src/*.c >> $list_c
-
-rm -f $list_obj
-
-for c_fname in `cat $list_c`; do
- obj_name=`curl_10char_object_name $c_fname`
- echo "$obj_name" >> $list_obj
-done
-
-sort -u $list_obj > $list_obj_uniq
-
-cnt_c=`cat $list_c | wc -l`
-cnt_u=`cat $list_obj_uniq | wc -l`
-
-echo ""
-echo ""
-echo ""
-if test $cnt_c -eq $cnt_u; then
- echo "10-characters-or-less generated object names are unique."
- obj_name_clash="no"
-else
- echo "10-characters-or-less generated object names are clashing..."
- obj_name_clash="yes"
-fi
-
-if test $obj_name_clash = "yes"; then
- #
- # Show clashing object names and respective source file names
- #
- echo ""
- paste $list_obj $list_c | sort > $list_obj_c
- prev_match="no"
- prev_line="unknown"
- prev_obj_name="unknown"
- while read this_line; do
- obj_name=`echo "$this_line" | cut -f1`
- if test "x$obj_name" = "x$prev_obj_name"; then
- if test "x$prev_match" != "xyes"; then
- echo "$prev_line"
- echo "$this_line"
- prev_match="yes"
- else
- echo "$this_line"
- fi
- else
- prev_match="no"
- fi
- prev_line=$this_line
- prev_obj_name=$obj_name
- done < $list_obj_c
-fi
-
-rm -f $list_c
-rm -f $list_obj
-rm -f $list_obj_c
-rm -f $list_obj_uniq
-
-# end of objnames-test10.sh
diff --git a/tests/objnames.inc b/tests/objnames.inc
deleted file mode 100644
index 158f80150..000000000
--- a/tests/objnames.inc
+++ /dev/null
@@ -1,107 +0,0 @@
-# ***************************************************************************
-# * _ _ ____ _
-# * Project ___| | | | _ \| |
-# * / __| | | | |_) | |
-# * | (__| |_| | _ <| |___
-# * \___|\___/|_| \_\_____|
-# *
-# * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
-# *
-# * This software is licensed as described in the file COPYING, which
-# * you should have received as part of this distribution. The terms
-# * are also available at https://curl.haxx.se/docs/copyright.html.
-# *
-# * You may opt to use, copy, modify, merge, publish, distribute and/or sell
-# * copies of the Software, and permit persons to whom the Software is
-# * furnished to do so, under the terms of the COPYING file.
-# *
-# * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
-# * KIND, either express or implied.
-# *
-# ***************************************************************************
-
-#
-# This file is sourced from curl/packages/OS400/initscript.sh and
-# other Bourne shell scripts. Keep it as portable as possible.
-#
-
-#
-# curl_10char_object_name
-#
-# This shell function accepts a single string argument with unspecified
-# length representing a (*.c) source file name and returns a string which
-# is a transformation of given argument.
-#
-# The intended purpose of this function is to transliterate a (*.c) source
-# file name that may be longer than 10 characters, or not, into a string
-# with at most 10 characters which may be used as an OS/400 object name.
-#
-# This function might not be universally useful, nor we care about it.
-#
-# It is intended to be used with libcurl's (*.c) source file names, so
-# dependency on libcurl's source file naming scheme is acceptable and
-# good enough for its intended use. Specifically it makes use of the fact
-# that libcurl's (*.c) source file names which may be longer than 10 chars
-# are conformed with underscore '_' separated substrings, or separated by
-# other character which does not belong to the [0-9], [a-z] or [A-Z] sets.
-#
-# This allows repeatable and automatic short object name generation with
-# no need for a hardcoded mapping table.
-#
-# Transformation is done in the following way:
-#
-# 1) Leading directory components are removed.
-# 2) Leftmost dot character and any other char following it are removed.
-# 3) Lowercase characters are transliterated to uppercase.
-# 4) Characters not in [A-Z] or [0-9] are transliterated to underscore '_'.
-# 5) Every sequence of one or more underscores is replaced with a single one.
-# 6) Five leftmost substrings which end in an underscore character are
-# replaced by the first character of each substring, while retaining
-# the rest of the string.
-# 7) Finally the result is truncated to 10 characters.
-#
-# Resulting object name may be shorter than 10 characters.
-#
-# Test case 1221 does unit testng of this function and also verifies
-# that it is possible to generate distinct short object names for all
-# curl and libcurl *.c source file names.
-#
-
-curl_10char_object_name() {
- echo "${1}" | \
- sed -e 's:.*/::' \
- -e 's:[.].*::' \
- -e 'y:abcdefghijklmnopqrstuvwxyz:ABCDEFGHIJKLMNOPQRSTUVWXYZ:' \
- -e 's:[^ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_]:_:g' \
- -e 's:__*:_:g' \
- -e 's:\([^_]\)[^_]*_\(.*\):\1\2:' \
- -e 's:\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3:' \
- -e 's:\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4:' \
- -e 's:\([^_]\)\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4\5:' \
- -e 's:\([^_]\)\([^_]\)\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4\5\6:' \
- -e 's:^\(..........\).*:\1:'
-}
-
-#
-# curl_8char_object_name
-#
-# Same as curl_10char_object_name() description and details above, except
-# that object name is limited to 8 characters maximum.
-#
-
-curl_8char_object_name() {
- echo "${1}" | \
- sed -e 's:.*/::' \
- -e 's:[.].*::' \
- -e 'y:abcdefghijklmnopqrstuvwxyz:ABCDEFGHIJKLMNOPQRSTUVWXYZ:' \
- -e 's:[^ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_]:_:g' \
- -e 's:__*:_:g' \
- -e 's:\([^_]\)[^_]*_\(.*\):\1\2:' \
- -e 's:\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3:' \
- -e 's:\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4:' \
- -e 's:\([^_]\)\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4\5:' \
- -e 's:\([^_]\)\([^_]\)\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4\5\6:' \
- -e 's:^\(........\).*:\1:'
-}
-
-# end of objectname.inc
diff --git a/tests/options-scan.pl b/tests/options-scan.pl
index d49352b40..1a644a77e 100644
--- a/tests/options-scan.pl
+++ b/tests/options-scan.pl
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -101,7 +101,7 @@ for my $c (sort @cmdopts) {
versioncheck($c, $oiv{$c});
}
else {
- print STDERR "$c is in the directory but not in file!\n";
+ print STDERR "--$c is in the option directory but not in $opts!\n";
$error++;
}
}
@@ -117,4 +117,6 @@ for my $v (sort @veropts) {
}
}
+print STDERR "ok\n" if(!$error);
+
exit $error;
diff --git a/tests/pathhelp.pm b/tests/pathhelp.pm
index f495306f6..f3bdc5bdf 100644
--- a/tests/pathhelp.pm
+++ b/tests/pathhelp.pm
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/rtspserver.pl.in b/tests/rtspserver.pl.in
index 83d24b7fe..09daa0eb5 100755
--- a/tests/rtspserver.pl.in
+++ b/tests/rtspserver.pl.in
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/runtests.1 b/tests/runtests.1
index 30a0bc29c..8f505a253 100644
--- a/tests/runtests.1
+++ b/tests/runtests.1
@@ -9,7 +9,7 @@
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
diff --git a/tests/runtests.pl.in b/tests/runtests.pl.in
index a8bfe16c4..710132ed8 100755
--- a/tests/runtests.pl.in
+++ b/tests/runtests.pl.in
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -163,6 +163,7 @@ my $TELNETPORT=$noport; # TELNET server port with negotiation
my $HTTPUNIXPATH; # HTTP server Unix domain socket path
my $SSHSRVMD5 = "[uninitialized]"; # MD5 of ssh server public key
+my $VERSION; # curl's reported version number
my $srcdir = $ENV{'srcdir'} || '.';
my $CURL="../src/gnurl".exe_ext('TOOL'); # what curl executable to run on the tests
@@ -255,6 +256,7 @@ my $has_cares; # set if built with c-ares
my $has_threadedres;# set if built with threaded resolver
my $has_psl; # set if libcurl is built with PSL support
my $has_altsvc; # set if libcurl is built with alt-svc support
+my $has_hsts; # set if libcurl is built with HSTS support
my $has_ldpreload; # set if curl is built for systems supporting LD_PRELOAD
my $has_multissl; # set if curl is build with MultiSSL support
my $has_manual; # set if curl is built with built-in manual
@@ -551,7 +553,7 @@ sub checkcmd {
my ($cmd)=@_;
my @paths=(split(":", $ENV{'PATH'}), "/usr/sbin", "/usr/local/sbin",
"/sbin", "/usr/bin", "/usr/local/bin",
- "./libtest/.libs", "./libtest");
+ "$LIBDIR/.libs", "$LIBDIR");
for(@paths) {
if( -x "$_/$cmd" && ! -d "$_/$cmd") {
# executable bit but not a directory!
@@ -1448,7 +1450,7 @@ sub runhttp2server {
# don't retry if the server doesn't work
if ($doesntrun{$pidfile}) {
- return (0,0);
+ return (0, 0, 0);
}
my $pid = processexists($pidfile);
@@ -1476,9 +1478,9 @@ sub runhttp2server {
if($http2pid <= 0 || !pidexists($http2pid)) {
# it is NOT alive
- logmsg "RUN: failed to start the $srvrname server\n";
stopserver($server, "$pid2");
$doesntrun{$pidfile} = 1;
+ $http2pid = $pid2 = 0;
next;
}
$doesntrun{$pidfile} = 0;
@@ -1489,6 +1491,8 @@ sub runhttp2server {
last;
}
+ logmsg "RUN: failed to start the $srvrname server\n" if(!$http2pid);
+
return ($http2pid, $pid2, $port);
}
@@ -1529,7 +1533,7 @@ sub runhttpserver {
# don't retry if the server doesn't work
if ($doesntrun{$pidfile}) {
- return (0,0);
+ return (0, 0, 0);
}
my $pid = processexists($pidfile);
@@ -1564,7 +1568,7 @@ sub runhttpserver {
stopserver($server, "$pid2");
displaylogs($testnumcheck);
$doesntrun{$pidfile} = 1;
- return (0,0);
+ return (0, 0, 0);
}
# where is it?
@@ -1581,7 +1585,7 @@ sub runhttpserver {
stopserver($server, "$httppid $pid2");
displaylogs($testnumcheck);
$doesntrun{$pidfile} = 1;
- return (0,0);
+ return (0, 0, 0);
}
$pid2 = $pid3;
@@ -1613,7 +1617,7 @@ sub runhttpsserver {
}
if(!$stunnel) {
- return (0,0);
+ return (0, 0, 0);
}
$server = servername_id($proto, $ipvnum, $idnum);
@@ -1622,7 +1626,7 @@ sub runhttpsserver {
# don't retry if the server doesn't work
if ($doesntrun{$pidfile}) {
- return (0,0);
+ return (0, 0, 0);
}
my $pid = processexists($pidfile);
@@ -1664,33 +1668,20 @@ sub runhttpsserver {
if($httpspid <= 0 || !pidexists($httpspid)) {
# it is NOT alive
- logmsg "RUN: failed to start the $srvrname server\n";
stopserver($server, "$pid2");
displaylogs($testnumcheck);
$doesntrun{$pidfile} = 1;
- next;
- }
-
- # Server is up. Verify that we can speak to it.
- $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
- if(!$pid3) {
- logmsg "RUN: $srvrname server failed verification\n";
- # failed to talk to it properly. Kill the server and return failure
- stopserver($server, "$httpspid $pid2");
- displaylogs($testnumcheck);
- $doesntrun{$pidfile} = 1;
+ $httpspid = $pid2 = 0;
next;
}
# we have a server!
+ if($verbose) {
+ logmsg "RUN: $srvrname server is PID $httpspid port $port\n";
+ }
last;
}
- # Here pid3 is actually the pid returned by the unsecure-http server.
-
$runcert{$server} = $certfile;
-
- if($verbose) {
- logmsg "RUN: $srvrname server is PID $httpspid port $port\n";
- }
+ logmsg "RUN: failed to start the $srvrname server\n" if(!$httpspid);
return ($httpspid, $pid2, $port);
}
@@ -1720,7 +1711,7 @@ sub runhttptlsserver {
# don't retry if the server doesn't work
if ($doesntrun{$pidfile}) {
- return (0,0);
+ return (0, 0, 0);
}
my $pid = processexists($pidfile);
@@ -1750,7 +1741,6 @@ sub runhttptlsserver {
if($httptlspid <= 0 || !pidexists($httptlspid)) {
# it is NOT alive
- logmsg "RUN: failed to start the $srvrname server\n";
stopserver($server, "$pid2");
displaylogs($testnumcheck);
$doesntrun{$pidfile} = 1;
@@ -1764,6 +1754,7 @@ sub runhttptlsserver {
}
last;
}
+ logmsg "RUN: failed to start the $srvrname server\n" if(!$httptlspid);
return ($httptlspid, $pid2, $port);
}
@@ -1877,7 +1868,7 @@ sub runpingpongserver {
}
else {
print STDERR "Unsupported protocol $proto!!\n";
- return 0;
+ return (0,0);
}
return ($pid2, $ftppid);
@@ -1908,7 +1899,7 @@ sub runftpsserver {
# don't retry if the server doesn't work
if ($doesntrun{$pidfile}) {
- return (0,0);
+ return (0, 0, 0);
}
my $pid = processexists($pidfile);
@@ -1943,24 +1934,14 @@ sub runftpsserver {
if($ftpspid <= 0 || !pidexists($ftpspid)) {
# it is NOT alive
- logmsg "RUN: failed to start the $srvrname server\n";
stopserver($server, "$pid2");
displaylogs($testnumcheck);
$doesntrun{$pidfile} = 1;
+ $ftpspid = $pid2 = 0;
next;
}
- $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
- if(!$pid3) {
- logmsg "RUN: $srvrname server failed verification\n";
- # failed to talk to it properly. Kill the server and return failure
- stopserver($server, "$ftpspid $pid2");
- displaylogs($testnumcheck);
- $doesntrun{$pidfile} = 1;
- next;
- }
- # Here pid3 is actually the pid returned by the unsecure-ftp server.
-
+ $doesntrun{$pidfile} = 0;
$runcert{$server} = $certfile;
if($verbose) {
@@ -1969,6 +1950,8 @@ sub runftpsserver {
last;
}
+ logmsg "RUN: failed to start the $srvrname server\n" if(!$ftpspid);
+
return ($ftpspid, $pid2, $port);
}
@@ -2000,7 +1983,7 @@ sub runtftpserver {
# don't retry if the server doesn't work
if ($doesntrun{$pidfile}) {
- return (0,0);
+ return (0, 0, 0);
}
my $pid = processexists($pidfile);
@@ -2029,7 +2012,7 @@ sub runtftpserver {
stopserver($server, "$pid2");
displaylogs($testnumcheck);
$doesntrun{$pidfile} = 1;
- return (0,0);
+ return (0, 0, 0);
}
my $port = pidfromfile($portfile);
@@ -2042,7 +2025,7 @@ sub runtftpserver {
stopserver($server, "$tftppid $pid2");
displaylogs($testnumcheck);
$doesntrun{$pidfile} = 1;
- return (0,0);
+ return (0, 0, 0);
}
$pid2 = $pid3;
@@ -2082,7 +2065,7 @@ sub runrtspserver {
# don't retry if the server doesn't work
if ($doesntrun{$pidfile}) {
- return (0,0);
+ return (0, 0, 0);
}
my $pid = processexists($pidfile);
@@ -2111,7 +2094,7 @@ sub runrtspserver {
stopserver($server, "$pid2");
displaylogs($testnumcheck);
$doesntrun{$pidfile} = 1;
- return (0,0);
+ return (0, 0, 0);
}
my $port = pidfromfile($portfile);
@@ -2124,7 +2107,7 @@ sub runrtspserver {
stopserver($server, "$rtsppid $pid2");
displaylogs($testnumcheck);
$doesntrun{$pidfile} = 1;
- return (0,0);
+ return (0, 0, 0);
}
$pid2 = $pid3;
@@ -2157,7 +2140,7 @@ sub runsshserver {
# don't retry if the server doesn't work
if ($doesntrun{$pidfile}) {
- return (0,0);
+ return (0, 0, 0);
}
my $sshd = find_sshd();
@@ -2207,27 +2190,12 @@ sub runsshserver {
# zero pid2 above.
if($sshpid <= 0 || !pidexists($sshpid)) {
# it is NOT alive
- logmsg "RUN: failed to start the $srvrname server on $port\n";
stopserver($server, "$pid2");
$doesntrun{$pidfile} = 1;
+ $sshpid = $pid2 = 0;
next;
}
- # ssh server verification allows some extra time for the server to
- # start up and gives us the opportunity of recovering the pid from the
- # pidfile, when this verification succeeds the recovered pid is
- # assigned to pid2.
-
- my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
- if(!$pid3) {
- logmsg "RUN: $srvrname server failed verification\n";
- # failed to fetch server pid. Kill the server and return failure
- stopserver($server, "$sshpid $pid2");
- $doesntrun{$pidfile} = 1;
- next;
- }
- $pid2 = $pid3;
-
# once it is known that the ssh server is alive, sftp server
# verification is performed actually connecting to it, authenticating
# and performing a very simple remote command. This verification is
@@ -2245,12 +2213,15 @@ sub runsshserver {
display_sshdconfig();
stopserver($server, "$sshpid $pid2");
$doesntrun{$pidfile} = 1;
+ $sshpid = $pid2 = 0;
next;
}
# we're happy, no need to loop anymore!
+ $doesntrun{$pidfile} = 0;
$wport = $port;
last;
}
+ logmsg "RUN: failed to start the $srvrname server on $port\n" if(!$sshpid);
if(!$wport) {
logmsg "RUN: couldn't start $srvrname. Tried these ports:";
@@ -2358,7 +2329,7 @@ sub runsocksserver {
# don't retry if the server doesn't work
if ($doesntrun{$pidfile}) {
- return (0,0);
+ return (0, 0, 0);
}
my $pid = processexists($pidfile);
@@ -2385,7 +2356,7 @@ sub runsocksserver {
logmsg "RUN: failed to start the $srvrname server\n";
stopserver($server, "$pid2");
$doesntrun{$pidfile} = 1;
- return (0,0);
+ return (0, 0, 0);
}
my $port = pidfromfile($portfile);
@@ -2422,7 +2393,7 @@ sub rundictserver {
# don't retry if the server doesn't work
if ($doesntrun{$pidfile}) {
- return (0,0);
+ return (0, 0, 0);
}
my $pid = processexists($pidfile);
@@ -2451,7 +2422,6 @@ sub rundictserver {
if($dictpid <= 0 || !pidexists($dictpid)) {
# it is NOT alive
- logmsg "RUN: failed to start the $srvrname server\n";
stopserver($server, "$pid2");
displaylogs($testnumcheck);
$doesntrun{$pidfile} = 1;
@@ -2465,6 +2435,7 @@ sub rundictserver {
}
last;
}
+ logmsg "RUN: failed to start the $srvrname server\n" if(!$dictpid);
return ($dictpid, $pid2, $port);
}
@@ -2494,7 +2465,7 @@ sub runsmbserver {
# don't retry if the server doesn't work
if ($doesntrun{$pidfile}) {
- return (0,0);
+ return (0, 0, 0);
}
my $pid = processexists($pidfile);
@@ -2523,7 +2494,6 @@ sub runsmbserver {
if($smbpid <= 0 || !pidexists($smbpid)) {
# it is NOT alive
- logmsg "RUN: failed to start the $srvrname server\n";
stopserver($server, "$pid2");
displaylogs($testnumcheck);
$doesntrun{$pidfile} = 1;
@@ -2537,6 +2507,7 @@ sub runsmbserver {
}
last;
}
+ logmsg "RUN: failed to start the $srvrname server\n" if(!$smbpid);
return ($smbpid, $pid2, $port);
}
@@ -2566,7 +2537,7 @@ sub runnegtelnetserver {
# don't retry if the server doesn't work
if ($doesntrun{$pidfile}) {
- return (0,0);
+ return (0, 0, 0);
}
my $pid = processexists($pidfile);
@@ -2594,7 +2565,6 @@ sub runnegtelnetserver {
if($ntelpid <= 0 || !pidexists($ntelpid)) {
# it is NOT alive
- logmsg "RUN: failed to start the $srvrname server\n";
stopserver($server, "$pid2");
displaylogs($testnumcheck);
$doesntrun{$pidfile} = 1;
@@ -2608,6 +2578,7 @@ sub runnegtelnetserver {
}
last;
}
+ logmsg "RUN: failed to start the $srvrname server\n" if(!$ntelpid);
return ($ntelpid, $pid2, $port);
}
@@ -2744,15 +2715,21 @@ sub cleardir {
my $file;
# Get all files
- opendir(DIR, $dir) ||
+ opendir(my $dh, $dir) ||
return 0; # can't open dir
- while($file = readdir(DIR)) {
- if(($file !~ /^\./)) {
- unlink("$dir/$file");
+ while($file = readdir($dh)) {
+ if(($file !~ /^(\.|\.\.)\z/)) {
+ if(-d "$dir/$file") {
+ cleardir("$dir/$file");
+ rmdir("$dir/$file");
+ }
+ else {
+ unlink("$dir/$file");
+ }
$count++;
}
}
- closedir DIR;
+ closedir $dh;
return $count;
}
@@ -2785,7 +2762,9 @@ sub compare {
}
sub setupfeatures {
+ $feature{"c-ares"} = $has_cares;
$feature{"alt-svc"} = $has_altsvc;
+ $feature{"HSTS"} = $has_hsts;
$feature{"brotli"} = $has_brotli;
$feature{"crypto"} = $has_crypto;
$feature{"debug"} = $debug_build;
@@ -2888,8 +2867,9 @@ sub checksystem {
for(@version) {
chomp;
- if($_ =~ /^curl/) {
+ if($_ =~ /^curl ([^ ]*)/) {
$curl = $_;
+ $VERSION = $1;
$curl =~ s/^(.*)(libcurl.*)/$1/g;
$libcurl = $2;
@@ -3058,6 +3038,9 @@ sub checksystem {
# alt-svc enabled
$has_altsvc=1;
}
+ if($feat =~ /HSTS/i) {
+ $has_hsts=1;
+ }
if($feat =~ /AsynchDNS/i) {
if(!$has_cares) {
# this means threaded resolver
@@ -3286,6 +3269,7 @@ sub subVariables {
$$thing =~ s/${prefix}CURL/$CURL/g;
$$thing =~ s/${prefix}PWD/$pwd/g;
$$thing =~ s/${prefix}POSIX_PWD/$posix_pwd/g;
+ $$thing =~ s/${prefix}VERSION/$VERSION/g;
my $file_pwd = $pwd;
if($file_pwd !~ /^\//) {
@@ -3329,6 +3313,20 @@ sub subBase64 {
# put the result into there
$$thing =~ s/%%B64%%/$enc/;
}
+ # hex decode
+ if($$thing =~ s/%hex\[(.*)\]hex%/%%HEX%%/i) {
+ # decode %NN characters
+ my $d = $1;
+ $d =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;
+ $$thing =~ s/%%HEX%%/$d/;
+ }
+ if($$thing =~ s/%repeat\[(\d+) x (.*)\]%/%%REPEAT%%/i) {
+ # decode %NN characters
+ my ($d, $n) = ($2, $1);
+ $d =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;
+ my $all = $d x $n;
+ $$thing =~ s/%%REPEAT%%/$all/;
+ }
}
sub fixarray {
@@ -3528,10 +3526,10 @@ sub singletest {
# create test result in CI services
if(azure_check_environment() && $AZURE_RUN_ID) {
- $AZURE_RESULT_ID = azure_create_test_result($AZURE_RUN_ID, $testnum, $testname);
+ $AZURE_RESULT_ID = azure_create_test_result($VCURL, $AZURE_RUN_ID, $testnum, $testname);
}
elsif(appveyor_check_environment()) {
- appveyor_create_test_result($testnum, $testname);
+ appveyor_create_test_result($VCURL, $testnum, $testname);
}
# remove test server commands file before servers are started/verified
@@ -3778,6 +3776,10 @@ sub singletest {
subVariables(\$fileContent);
open(OUTFILE, ">$filename");
binmode OUTFILE; # for crapage systems, use binary
+ if($fileattr{'nonewline'}) {
+ # cut off the final newline
+ chomp($fileContent);
+ }
print OUTFILE $fileContent;
close(OUTFILE);
}
@@ -3953,11 +3955,11 @@ sub singletest {
if ($torture) {
$cmdres = torture($CMDLINE,
$testnum,
- "$gdb --directory libtest $DBGCURL -x $LOGDIR/gdbcmd");
+ "$gdb --directory $LIBDIR $DBGCURL -x $LOGDIR/gdbcmd");
}
elsif($gdbthis) {
my $GDBW = ($gdbxwin) ? "-w" : "";
- runclient("$gdb --directory libtest $DBGCURL $GDBW -x $LOGDIR/gdbcmd");
+ runclient("$gdb --directory $LIBDIR $DBGCURL $GDBW -x $LOGDIR/gdbcmd");
$cmdres=0; # makes it always continue after a debugged run
}
else {
@@ -5184,9 +5186,9 @@ disabledtests("$TESTDIR/DISABLED.local");
# Check options to this test program
#
-# Special case for CMake: replace '${TFLAGS}' by the contents of the
+# Special case for CMake: replace '$TFLAGS' by the contents of the
# environment variable (if any).
-if(@ARGV && $ARGV[-1] eq '${TFLAGS}') {
+if(@ARGV && $ARGV[-1] eq '$TFLAGS') {
pop @ARGV;
push(@ARGV, split(' ', $ENV{'TFLAGS'})) if defined($ENV{'TFLAGS'});
}
@@ -5687,7 +5689,7 @@ sub displaylogs {
#
if(azure_check_environment()) {
- $AZURE_RUN_ID = azure_create_test_run();
+ $AZURE_RUN_ID = azure_create_test_run($VCURL);
logmsg "Azure Run ID: $AZURE_RUN_ID\n" if ($verbose);
}
@@ -5715,11 +5717,11 @@ foreach $testnum (@at) {
# update test result in CI services
if(azure_check_environment() && $AZURE_RUN_ID && $AZURE_RESULT_ID) {
- $AZURE_RESULT_ID = azure_update_test_result($AZURE_RUN_ID, $AZURE_RESULT_ID, $testnum, $error,
+ $AZURE_RESULT_ID = azure_update_test_result($VCURL, $AZURE_RUN_ID, $AZURE_RESULT_ID, $testnum, $error,
$timeprepini{$testnum}, $timevrfyend{$testnum});
}
elsif(appveyor_check_environment()) {
- appveyor_update_test_result($testnum, $error, $timeprepini{$testnum}, $timevrfyend{$testnum});
+ appveyor_update_test_result($VCURL, $testnum, $error, $timeprepini{$testnum}, $timevrfyend{$testnum});
}
if($error < 0) {
@@ -5764,7 +5766,7 @@ my $sofar = time() - $start;
#
if(azure_check_environment() && $AZURE_RUN_ID) {
- $AZURE_RUN_ID = azure_update_test_run($AZURE_RUN_ID);
+ $AZURE_RUN_ID = azure_update_test_run($VCURL, $AZURE_RUN_ID);
}
# Tests done, stop the servers
@@ -5779,11 +5781,18 @@ if($total) {
$ok/$total*100);
if($ok != $total) {
- logmsg "TESTFAIL: These test cases failed: $failed\n";
+ logmsg "\nTESTFAIL: These test cases failed: $failed\n\n";
}
}
else {
- logmsg "TESTFAIL: No tests were performed\n";
+ logmsg "\nTESTFAIL: No tests were performed\n\n";
+ if(scalar(keys %enabled_keywords)) {
+ logmsg "TESTFAIL: Nothing matched these keywords: ";
+ for(keys %enabled_keywords) {
+ logmsg "$_ ";
+ }
+ logmsg "\n";
+ }
}
if($all) {
@@ -5820,6 +5829,6 @@ if($skipped && !$short) {
}
}
-if($total && (($ok+$ign) != $total)) {
+if(($total && (($ok+$ign) != $total)) || !$total) {
exit 1;
}
diff --git a/tests/secureserver.pl.in b/tests/secureserver.pl.in
index bf6fc079a..22bcdc242 100755
--- a/tests/secureserver.pl.in
+++ b/tests/secureserver.pl.in
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/server/CMakeLists.txt b/tests/server/CMakeLists.txt
index e07abf6fa..0c93efdaa 100644
--- a/tests/server/CMakeLists.txt
+++ b/tests/server/CMakeLists.txt
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/server/Makefile.am b/tests/server/Makefile.am
index a5b98130c..3a89b5f33 100644
--- a/tests/server/Makefile.am
+++ b/tests/server/Makefile.am
@@ -5,11 +5,11 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/server/Makefile.inc b/tests/server/Makefile.inc
index 55bc3a737..35d4dbaa1 100644
--- a/tests/server/Makefile.inc
+++ b/tests/server/Makefile.inc
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/server/base64.pl b/tests/server/base64.pl
index d00673ec9..e1b88cf58 100755
--- a/tests/server/base64.pl
+++ b/tests/server/base64.pl
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/server/disabled.c b/tests/server/disabled.c
index c82847d8e..0e862177d 100644
--- a/tests/server/disabled.c
+++ b/tests/server/disabled.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/server/fake_ntlm.c b/tests/server/fake_ntlm.c
index c9211f7ea..ae281ca1c 100644
--- a/tests/server/fake_ntlm.c
+++ b/tests/server/fake_ntlm.c
@@ -10,7 +10,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/server/getpart.c b/tests/server/getpart.c
index 664d81569..483d37802 100644
--- a/tests/server/getpart.c
+++ b/tests/server/getpart.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/server/getpart.h b/tests/server/getpart.h
index e8ddd22aa..211139205 100644
--- a/tests/server/getpart.h
+++ b/tests/server/getpart.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/server/mqttd.c b/tests/server/mqttd.c
index 6785b0014..1f4344ac0 100644
--- a/tests/server/mqttd.c
+++ b/tests/server/mqttd.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -486,6 +486,7 @@ static curl_socket_t mqttit(curl_socket_t fd)
size_t bytes = 0; /* remaining length field size in bytes */
char client_id[MAX_CLIENT_ID_LENGTH];
long testno;
+ FILE *stream = NULL;
static const char protocol[7] = {
0x00, 0x04, /* protocol length */
@@ -550,7 +551,6 @@ static curl_socket_t mqttit(curl_socket_t fd)
}
}
else if(byte == MQTT_MSG_SUBSCRIBE) {
- FILE *stream;
int error;
char *data;
size_t datalen;
@@ -636,7 +636,10 @@ static curl_socket_t mqttit(curl_socket_t fd)
} while(1);
end:
- fclose(dump);
+ if(dump)
+ fclose(dump);
+ if(stream)
+ fclose(stream);
return CURL_SOCKET_BAD;
}
diff --git a/tests/server/resolve.c b/tests/server/resolve.c
index f72561879..6905b7e78 100644
--- a/tests/server/resolve.c
+++ b/tests/server/resolve.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/server/rtspd.c b/tests/server/rtspd.c
index 6ee7787b1..39f6d1413 100644
--- a/tests/server/rtspd.c
+++ b/tests/server/rtspd.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/server/server_setup.h b/tests/server/server_setup.h
index 1f2cef10c..e406a3d83 100644
--- a/tests/server/server_setup.h
+++ b/tests/server/server_setup.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/server/server_sockaddr.h b/tests/server/server_sockaddr.h
index c3602e1cf..e72531179 100644
--- a/tests/server/server_sockaddr.h
+++ b/tests/server/server_sockaddr.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/server/sockfilt.c b/tests/server/sockfilt.c
index 6b3758c94..dd7ada09f 100644
--- a/tests/server/sockfilt.c
+++ b/tests/server/sockfilt.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -705,7 +705,7 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds,
if(FD_ISSET(wsasock, writefds)) {
FD_SET(wsasock, &writesock);
- wsaevents.lNetworkEvents |= FD_WRITE|FD_CONNECT;
+ wsaevents.lNetworkEvents |= FD_WRITE|FD_CONNECT|FD_CLOSE;
}
if(FD_ISSET(wsasock, exceptfds)) {
@@ -835,11 +835,11 @@ static int select_ws(int nfds, fd_set *readfds, fd_set *writefds,
FD_CLR(wsasock, readfds);
/* remove from descriptor set if not ready for write/connect */
- if(!(wsaevents.lNetworkEvents & (FD_WRITE|FD_CONNECT)))
+ if(!(wsaevents.lNetworkEvents & (FD_WRITE|FD_CONNECT|FD_CLOSE)))
FD_CLR(wsasock, writefds);
/* remove from descriptor set if not exceptional */
- if(!(wsaevents.lNetworkEvents & (FD_OOB)))
+ if(!(wsaevents.lNetworkEvents & FD_OOB))
FD_CLR(wsasock, exceptfds);
}
}
diff --git a/tests/server/socksd.c b/tests/server/socksd.c
index e6e9c12b0..e8b71bedf 100644
--- a/tests/server/socksd.c
+++ b/tests/server/socksd.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/server/sws.c b/tests/server/sws.c
index b0f2a83d6..74dd3a778 100644
--- a/tests/server/sws.c
+++ b/tests/server/sws.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/server/testpart.c b/tests/server/testpart.c
index 9c295e0f5..1ea9c2004 100644
--- a/tests/server/testpart.c
+++ b/tests/server/testpart.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/server/tftp.h b/tests/server/tftp.h
index 62a0cc35e..569967222 100644
--- a/tests/server/tftp.h
+++ b/tests/server/tftp.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/server/tftpd.c b/tests/server/tftpd.c
index 4215bfe4a..92d584918 100644
--- a/tests/server/tftpd.c
+++ b/tests/server/tftpd.c
@@ -821,11 +821,6 @@ int main(int argc, char **argv)
sclose(peer);
peer = CURL_SOCKET_BAD;
- if(test.ofile > 0) {
- close(test.ofile);
- test.ofile = 0;
- }
-
if(got_exit_signal)
break;
@@ -1304,6 +1299,11 @@ send_ack:
}
} while(size == SEGSIZE);
write_behind(test, pf->f_convert);
+ /* close the output file as early as possible after upload completion */
+ if(test->ofile > 0) {
+ close(test->ofile);
+ test->ofile = 0;
+ }
rap->th_opcode = htons((unsigned short)opcode_ACK); /* send the "final"
ack */
@@ -1326,6 +1326,11 @@ send_ack:
(void) swrite(peer, &ackbuf.storage[0], 4); /* resend final ack */
}
abort:
+ /* make sure the output file is closed in case of abort */
+ if(test->ofile > 0) {
+ close(test->ofile);
+ test->ofile = 0;
+ }
return;
}
diff --git a/tests/server/util.c b/tests/server/util.c
index dccce596b..bfd133cec 100644
--- a/tests/server/util.c
+++ b/tests/server/util.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -167,8 +167,8 @@ void win32_init(void)
WORD wVersionRequested;
WSADATA wsaData;
int err;
- wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
+ wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if(err != 0) {
@@ -177,8 +177,8 @@ void win32_init(void)
exit(1);
}
- if(LOBYTE(wsaData.wVersion) != USE_WINSOCK ||
- HIBYTE(wsaData.wVersion) != USE_WINSOCK) {
+ if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
+ HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) {
WSACleanup();
perror("Winsock init failed");
logmsg("No suitable winsock.dll found -- aborting");
@@ -682,13 +682,14 @@ static DWORD WINAPI main_window_loop(LPVOID lpParameter)
ZeroMemory(&wc, sizeof(wc));
wc.lpfnWndProc = (WNDPROC)main_window_proc;
wc.hInstance = (HINSTANCE)lpParameter;
- wc.lpszClassName = "MainWClass";
+ wc.lpszClassName = TEXT("MainWClass");
if(!RegisterClass(&wc)) {
perror("RegisterClass failed");
return (DWORD)-1;
}
- hidden_main_window = CreateWindowEx(0, "MainWClass", "Recv WM_CLOSE msg",
+ hidden_main_window = CreateWindowEx(0, TEXT("MainWClass"),
+ TEXT("Recv WM_CLOSE msg"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
diff --git a/tests/server/util.h b/tests/server/util.h
index 629539205..68473f28f 100644
--- a/tests/server/util.h
+++ b/tests/server/util.h
@@ -11,7 +11,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/serverhelp.pm b/tests/serverhelp.pm
index 466091fcc..83f783af8 100644
--- a/tests/serverhelp.pm
+++ b/tests/serverhelp.pm
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/smbserver.py.in b/tests/smbserver.py.in
index f752c17a2..a00ecae3b 100755
--- a/tests/smbserver.py.in
+++ b/tests/smbserver.py.in
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -21,21 +21,23 @@
#
"""Server for testing SMB"""
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
# NOTE: the impacket configuration is not unicode_literals compatible!
+
import argparse
+import logging
import os
import sys
-import logging
import tempfile
+
+# Import our curl test data helper
+from util import ClosingFileHandler, TestData
+
if sys.version_info.major >= 3:
import configparser
else:
import ConfigParser as configparser
-# Import our curl test data helper
-import curl_test_data
-
# impacket needs to be installed in the Python environment
try:
import impacket
@@ -43,10 +45,10 @@ except ImportError:
sys.stderr.write('Python package impacket needs to be installed!\n')
sys.stderr.write('Use pip or your package manager to install it.\n')
sys.exit(1)
-from impacket import smbserver as imp_smbserver
from impacket import smb as imp_smb
-from impacket.nt_errors import (STATUS_ACCESS_DENIED, STATUS_SUCCESS,
- STATUS_NO_SUCH_FILE)
+from impacket import smbserver as imp_smbserver
+from impacket.nt_errors import (STATUS_ACCESS_DENIED, STATUS_NO_SUCH_FILE,
+ STATUS_SUCCESS)
log = logging.getLogger(__name__)
SERVER_MAGIC = "SERVER_MAGIC"
@@ -120,7 +122,7 @@ class TestSmbServer(imp_smbserver.SMBSERVER):
config_parser=config_parser)
# Set up a test data object so we can get test data later.
- self.ctd = curl_test_data.TestData(test_data_directory)
+ self.ctd = TestData(test_data_directory)
# Override smbComNtCreateAndX so we can pretend to have files which
# don't exist.
@@ -353,7 +355,7 @@ def setup_logging(options):
# Write out to a logfile
if options.logfile:
- handler = logging.FileHandler(options.logfile, mode="w")
+ handler = ClosingFileHandler(options.logfile)
handler.setFormatter(formatter)
handler.setLevel(logging.DEBUG)
root_logger.addHandler(handler)
diff --git a/tests/sshhelp.pm b/tests/sshhelp.pm
index cd7f58fc1..0f71b3079 100644
--- a/tests/sshhelp.pm
+++ b/tests/sshhelp.pm
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/sshserver.pl.in b/tests/sshserver.pl.in
index fd98d48cc..4b3d7eb3c 100644
--- a/tests/sshserver.pl.in
+++ b/tests/sshserver.pl.in
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/symbol-scan.pl.in b/tests/symbol-scan.pl.in
index a9853c2c4..5d8bad168 100755
--- a/tests/symbol-scan.pl.in
+++ b/tests/symbol-scan.pl.in
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -176,7 +176,7 @@ if($summary) {
}
if($misses) {
- exit 2; # there are stuff to attend to!
+ exit 0; # there are stuff to attend to!
}
else {
print "OK\n";
diff --git a/tests/testcurl.1 b/tests/testcurl.1
index ee07d64fe..bd7562443 100644
--- a/tests/testcurl.1
+++ b/tests/testcurl.1
@@ -5,11 +5,11 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
-.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
@@ -32,7 +32,7 @@ crontab job or similar at a regular interval. The output is suitable to be
mailed to curl-autocompile@haxx.se to be dealt with automatically (make sure
the subject includes the word "autobuild" as the mail gets silently discarded
otherwise). The most current build status (with a reasonable backlog) will be
-published on the curl site, at https://curl.haxx.se/dev/builds.html
+published on the curl site, at https://curl.se/dev/builds.html
\fIoptions\fP may be omitted. See \fI--setup\fP for what happens then.
@@ -79,7 +79,7 @@ Specify your target environment. Recognized strings include 'vc', 'mingw32',
.SH "INITIAL SETUP"
First you make a checkout from git (or you write a script that downloads daily
snapshots automatically, find inspiration in
-https://curl.haxx.se/dev/autocurl.txt ):
+https://curl.se/dev/autocurl.txt ):
.nf
$ mkdir daily-curl
diff --git a/tests/testcurl.pl.in b/tests/testcurl.pl.in
index b1008f606..de30edf07 100755
--- a/tests/testcurl.pl.in
+++ b/tests/testcurl.pl.in
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -32,7 +32,7 @@
# curl-autocompile@haxx.se to be dealt with automatically (make sure the
# subject includes the word "autobuild" as the mail gets silently discarded
# otherwise). The most current build status (with a reasonable backlog) will
-# be published on the curl site, at https://curl.haxx.se/auto/
+# be published on the curl site, at https://curl.se/auto/
# USAGE:
# testcurl.pl [options] [curl-daily-name] > output
@@ -481,21 +481,13 @@ if ($git) {
open(LOG, ">$buildlog") or die;
while (<F>) {
my $ll = $_;
- # ignore messages pertaining to third party m4 files we don't care
- next if ($ll =~ /aclocal\/gtk\.m4/);
- next if ($ll =~ /aclocal\/gtkextra\.m4/);
print $ll;
print LOG $ll;
}
close(F);
close(LOG);
- if (grepfile("^buildconf: OK", $buildlog)) {
- logit "buildconf was successful";
- }
- else {
- mydie "buildconf was NOT successful";
- }
+ logit "buildconf was successful";
}
else {
logit "buildconf was successful (dummy message)";
diff --git a/tests/tftpserver.pl.in b/tests/tftpserver.pl.in
index 891b0ec40..a82a58a3a 100755
--- a/tests/tftpserver.pl.in
+++ b/tests/tftpserver.pl.in
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt
index c5def5328..4bb48ab63 100644
--- a/tests/unit/CMakeLists.txt
+++ b/tests/unit/CMakeLists.txt
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am
index 5055aa86b..e2fdd8760 100644
--- a/tests/unit/Makefile.am
+++ b/tests/unit/Makefile.am
@@ -5,11 +5,11 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
-# Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -48,7 +48,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include \
-I$(top_srcdir)/tests/libtest
endif
-EXTRA_DIST = Makefile.inc
+EXTRA_DIST = Makefile.inc CMakeLists.txt README.md
CFLAGS += @CURL_CFLAG_EXTRAS@
diff --git a/tests/unit/Makefile.inc b/tests/unit/Makefile.inc
index 158619657..c3cb7ed22 100644
--- a/tests/unit/Makefile.inc
+++ b/tests/unit/Makefile.inc
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -34,7 +34,8 @@ UNITPROGS = unit1300 unit1301 unit1302 unit1303 unit1304 unit1305 unit1307 \
unit1600 unit1601 unit1602 unit1603 unit1604 unit1605 unit1606 unit1607 \
unit1608 unit1609 unit1610 unit1611 unit1612 \
unit1620 unit1621 \
- unit1650 unit1651 unit1652 unit1653 unit1654 unit1655
+ unit1650 unit1651 unit1652 unit1653 unit1654 unit1655 \
+ unit1660
unit1300_SOURCES = unit1300.c $(UNITFILES)
unit1300_CPPFLAGS = $(AM_CPPFLAGS)
@@ -154,3 +155,5 @@ unit1654_CPPFLAGS = $(AM_CPPFLAGS)
unit1655_SOURCES = unit1655.c $(UNITFILES)
unit1655_CPPFLAGS = $(AM_CPPFLAGS)
+unit1660_SOURCES = unit1660.c $(UNITFILES)
+unit1660_CPPFLAGS = $(AM_CPPFLAGS)
diff --git a/tests/unit/README b/tests/unit/README.md
index 060b670c6..2880d1979 100644
--- a/tests/unit/README
+++ b/tests/unit/README.md
@@ -1,50 +1,44 @@
-Unit tests
-==========
+# Unit tests
-The goal is to add tests for *ALL* functions in libcurl. If functions are too
+The goal is to add tests for *all* functions in libcurl. If functions are too
big and complicated, we should split them into smaller and testable ones.
-Build Unit Tests
-================
+## Build Unit Tests
-'./configure --enable-debug' is required for the unit tests to build. To
+`./configure --enable-debug` is required for the unit tests to build. To
enable unit tests, there will be a separate static libcurl built that will be
used exclusively for linking unit test programs. Just build everything as
normal, and then you can run the unit test cases as well.
-Run Unit Tests
-==============
+## Run Unit Tests
Unit tests are run as part of the regular test suite. If you have built
everything to run unit tests, to can do 'make test' at the root level. Or you
-can 'cd tests' and 'make' and then invoke individual unit tests with
-./runtests.pl NNNN where NNNN is the specific test number.
+can `cd tests` and `make` and then invoke individual unit tests with
+`./runtests.pl NNNN` where `NNNN` is the specific test number.
-Debug Unit Tests
-================
+## Debug Unit Tests
If a specific test fails you will get told. The test case then has output left
in the log/ subdirectory, but most importantly you can re-run the test again
-using gdb by doing ./runtests.pl -g NNNN. That is, add a -g to make it start
-up gdb and run the same case using that.
+using gdb by doing `./runtests.pl -g NNNN`. That is, add a `-g` to make it
+start up gdb and run the same case using that.
-Write Unit Tests
-================
+## Write Unit Tests
We put tests that focus on an area or a specific function into a single C
source file. The source file should be named 'unitNNNN.c' where NNNN is a
-number that starts with 1300 and you can pick the next free number.
+previously unused number.
-Add your test to tests/unit/Makefile.inc (if it is a unit test).
-Add your test data to tests/data/Makefile.inc
+Add your test to `tests/unit/Makefile.inc` (if it is a unit test). Add your
+test data file name to `tests/data/Makefile.inc`
-You also need a separate file called tests/data/testNNNN (using the same
+You also need a separate file called `tests/data/testNNNN` (using the same
number) that describes your test case. See the test1300 file for inspiration
-and the tests/FILEFORMAT documentation.
+and the `tests/FILEFORMAT.md` documentation.
For the actual C file, here's a very simple example:
-
------------------------ start -------------------------------
+~~~c
#include "curlcheck.h"
#include "a libcurl header.h" /* from the lib dir */
@@ -70,5 +64,3 @@ UNITTEST_START
/* you end the test code like this: */
UNITTEST_STOP
-
------------------------ end -------------------------------
diff --git a/tests/unit/curlcheck.h b/tests/unit/curlcheck.h
index 016119a39..88bbdcb52 100644
--- a/tests/unit/curlcheck.h
+++ b/tests/unit/curlcheck.h
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1300.c b/tests/unit/unit1300.c
index 3e4c33ccc..aba068a00 100644
--- a/tests/unit/unit1300.c
+++ b/tests/unit/unit1300.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -23,11 +23,11 @@
#include "llist.h"
-static struct curl_llist llist;
+static struct Curl_llist llist;
-static struct curl_llist llist_destination;
+static struct Curl_llist llist_destination;
-static void test_curl_llist_dtor(void *key, void *value)
+static void test_Curl_llist_dtor(void *key, void *value)
{
/* used by the llist API, does nothing here */
(void)key;
@@ -36,8 +36,8 @@ static void test_curl_llist_dtor(void *key, void *value)
static CURLcode unit_setup(void)
{
- Curl_llist_init(&llist, test_curl_llist_dtor);
- Curl_llist_init(&llist_destination, test_curl_llist_dtor);
+ Curl_llist_init(&llist, test_Curl_llist_dtor);
+ Curl_llist_init(&llist_destination, test_Curl_llist_dtor);
return CURLE_OK;
}
@@ -50,14 +50,14 @@ UNITTEST_START
int unusedData_case1 = 1;
int unusedData_case2 = 2;
int unusedData_case3 = 3;
- struct curl_llist_element case1_list;
- struct curl_llist_element case2_list;
- struct curl_llist_element case3_list;
- struct curl_llist_element case4_list;
- struct curl_llist_element *head;
- struct curl_llist_element *element_next;
- struct curl_llist_element *element_prev;
- struct curl_llist_element *to_remove;
+ struct Curl_llist_element case1_list;
+ struct Curl_llist_element case2_list;
+ struct Curl_llist_element case3_list;
+ struct Curl_llist_element case4_list;
+ struct Curl_llist_element *head;
+ struct Curl_llist_element *element_next;
+ struct Curl_llist_element *element_prev;
+ struct Curl_llist_element *to_remove;
size_t llist_size = Curl_llist_count(&llist);
/**
@@ -74,8 +74,8 @@ UNITTEST_START
fail_unless(llist.size == 0, "list initial size should be zero");
fail_unless(llist.head == NULL, "list head should initiate to NULL");
fail_unless(llist.tail == NULL, "list tail should intiate to NULL");
- fail_unless(llist.dtor == test_curl_llist_dtor,
- "list dtor should initiate to test_curl_llist_dtor");
+ fail_unless(llist.dtor == test_Curl_llist_dtor,
+ "list dtor should initiate to test_Curl_llist_dtor");
/**
* testing Curl_llist_insert_next
diff --git a/tests/unit/unit1301.c b/tests/unit/unit1301.c
index 2af60bef4..ec5787405 100644
--- a/tests/unit/unit1301.c
+++ b/tests/unit/unit1301.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1302.c b/tests/unit/unit1302.c
index bd240d52c..8cc485d58 100644
--- a/tests/unit/unit1302.c
+++ b/tests/unit/unit1302.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1303.c b/tests/unit/unit1303.c
index 945b82ba7..16ec09816 100644
--- a/tests/unit/unit1303.c
+++ b/tests/unit/unit1303.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1304.c b/tests/unit/unit1304.c
index c1d36e840..a6dc64d6c 100644
--- a/tests/unit/unit1304.c
+++ b/tests/unit/unit1304.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1305.c b/tests/unit/unit1305.c
index 50f6da8bb..2432ebef2 100644
--- a/tests/unit/unit1305.c
+++ b/tests/unit/unit1305.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -40,7 +40,7 @@
#include "memdebug.h" /* LAST include file */
static struct Curl_easy *data;
-static struct curl_hash hp;
+static struct Curl_hash hp;
static char *data_key;
static struct Curl_dns_entry *data_node;
diff --git a/tests/unit/unit1307.c b/tests/unit/unit1307.c
index 7e88ea4d9..a657b61cf 100644
--- a/tests/unit/unit1307.c
+++ b/tests/unit/unit1307.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1308.c b/tests/unit/unit1308.c
index 27624a648..b46072378 100644
--- a/tests/unit/unit1308.c
+++ b/tests/unit/unit1308.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1309.c b/tests/unit/unit1309.c
index 880530313..5a2c154b0 100644
--- a/tests/unit/unit1309.c
+++ b/tests/unit/unit1309.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -99,7 +99,7 @@ UNITTEST_START
splayprint(root, 0, 1);
printf("remove pointer %d, payload %zu\n", rem,
*(size_t *)nodes[rem].payload);
- rc = Curl_splayremovebyaddr(root, &nodes[rem], &root);
+ rc = Curl_splayremove(root, &nodes[rem], &root);
if(rc) {
/* failed! */
printf("remove %d failed!\n", rem);
diff --git a/tests/unit/unit1323.c b/tests/unit/unit1323.c
index 1adb27494..165825323 100644
--- a/tests/unit/unit1323.c
+++ b/tests/unit/unit1323.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1330.c b/tests/unit/unit1330.c
index c9f19ccc5..b365798b8 100644
--- a/tests/unit/unit1330.c
+++ b/tests/unit/unit1330.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1394.c b/tests/unit/unit1394.c
index d6644f8eb..035ccf584 100644
--- a/tests/unit/unit1394.c
+++ b/tests/unit/unit1394.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1395.c b/tests/unit/unit1395.c
index b8440b477..c362cc3be 100644
--- a/tests/unit/unit1395.c
+++ b/tests/unit/unit1395.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1396.c b/tests/unit/unit1396.c
index 4dd25b40d..66f8fc156 100644
--- a/tests/unit/unit1396.c
+++ b/tests/unit/unit1396.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1397.c b/tests/unit/unit1397.c
index 432b90973..508f41af9 100644
--- a/tests/unit/unit1397.c
+++ b/tests/unit/unit1397.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1398.c b/tests/unit/unit1398.c
index b29bc0830..1e62e2fc9 100644
--- a/tests/unit/unit1398.c
+++ b/tests/unit/unit1398.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1399.c b/tests/unit/unit1399.c
index 3b52989e4..261e0b115 100644
--- a/tests/unit/unit1399.c
+++ b/tests/unit/unit1399.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1600.c b/tests/unit/unit1600.c
index 4e774aabb..a76fab270 100644
--- a/tests/unit/unit1600.c
+++ b/tests/unit/unit1600.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1601.c b/tests/unit/unit1601.c
index bf00bc7e9..4bee3f078 100644
--- a/tests/unit/unit1601.c
+++ b/tests/unit/unit1601.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1602.c b/tests/unit/unit1602.c
index 5f1ee9f47..ee6acacc5 100644
--- a/tests/unit/unit1602.c
+++ b/tests/unit/unit1602.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -28,7 +28,7 @@
#include "memdebug.h" /* LAST include file */
-static struct curl_hash hash_static;
+static struct Curl_hash hash_static;
static void mydtor(void *p)
{
diff --git a/tests/unit/unit1603.c b/tests/unit/unit1603.c
index c20b20b0e..f9170ef99 100644
--- a/tests/unit/unit1603.c
+++ b/tests/unit/unit1603.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2015 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2015 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -28,7 +28,7 @@
#include "memdebug.h" /* LAST include file */
-static struct curl_hash hash_static;
+static struct Curl_hash hash_static;
static const int slots = 3;
static void mydtor(void *p)
diff --git a/tests/unit/unit1604.c b/tests/unit/unit1604.c
index 9c4f77670..d811858df 100644
--- a/tests/unit/unit1604.c
+++ b/tests/unit/unit1604.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -82,7 +82,6 @@ struct data {
};
UNITTEST_START
-
{ /* START sanitize_file_name */
struct data data[] = {
{ "", 0,
@@ -349,7 +348,6 @@ UNITTEST_START
#else
UNITTEST_START
-
{
fprintf(stderr, "Skipped test not for this platform\n");
}
diff --git a/tests/unit/unit1605.c b/tests/unit/unit1605.c
index 0ec726a72..9a77da2f0 100644
--- a/tests/unit/unit1605.c
+++ b/tests/unit/unit1605.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1606.c b/tests/unit/unit1606.c
index 9da0b70b6..7ef344b2c 100644
--- a/tests/unit/unit1606.c
+++ b/tests/unit/unit1606.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1607.c b/tests/unit/unit1607.c
index e8d412080..f1016837b 100644
--- a/tests/unit/unit1607.c
+++ b/tests/unit/unit1607.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1608.c b/tests/unit/unit1608.c
index fc767d1d5..5243cd7cd 100644
--- a/tests/unit/unit1608.c
+++ b/tests/unit/unit1608.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1609.c b/tests/unit/unit1609.c
index ce3ddf9d8..76d295b7c 100644
--- a/tests/unit/unit1609.c
+++ b/tests/unit/unit1609.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1610.c b/tests/unit/unit1610.c
index bb9c937c9..2a18f5c5f 100644
--- a/tests/unit/unit1610.c
+++ b/tests/unit/unit1610.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1611.c b/tests/unit/unit1611.c
index bc19f8a5c..948484b53 100644
--- a/tests/unit/unit1611.c
+++ b/tests/unit/unit1611.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1612.c b/tests/unit/unit1612.c
index 3fb2de033..caddd02a0 100644
--- a/tests/unit/unit1612.c
+++ b/tests/unit/unit1612.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1620.c b/tests/unit/unit1620.c
index b23e5b912..4f1aaaf0a 100644
--- a/tests/unit/unit1620.c
+++ b/tests/unit/unit1620.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1621.c b/tests/unit/unit1621.c
index 618abedfa..ec361dfbf 100644
--- a/tests/unit/unit1621.c
+++ b/tests/unit/unit1621.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1650.c b/tests/unit/unit1650.c
index b2fc89efa..de54c0841 100644
--- a/tests/unit/unit1650.c
+++ b/tests/unit/unit1650.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1651.c b/tests/unit/unit1651.c
index 44dbf4b51..07e5b3f7a 100644
--- a/tests/unit/unit1651.c
+++ b/tests/unit/unit1651.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -35,7 +35,7 @@ static void unit_stop(void)
#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \
defined(USE_WOLFSSL) || defined(USE_SCHANNEL)
-/* cert captured from gdb when connecting to curl.haxx.se on October 26
+/* cert captured from gdb when connecting to curl.se on October 26
2018 */
static unsigned char cert[] = {
0x30, 0x82, 0x0F, 0x5B, 0x30, 0x82, 0x0E, 0x43, 0xA0, 0x03, 0x02, 0x01, 0x02,
diff --git a/tests/unit/unit1652.c b/tests/unit/unit1652.c
index 9693fe63a..2500ce95f 100644
--- a/tests/unit/unit1652.c
+++ b/tests/unit/unit1652.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1653.c b/tests/unit/unit1653.c
index 8d4eb915d..618e76d48 100644
--- a/tests/unit/unit1653.c
+++ b/tests/unit/unit1653.c
@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -55,7 +55,7 @@ UNITTEST_START
ipv6port = strdup("[fe80::250:56ff:fea7:da15]");
if(!ipv6port)
goto fail;
- ret = Curl_parse_port(u, ipv6port);
+ ret = Curl_parse_port(u, ipv6port, FALSE);
fail_unless(ret == CURLUE_OK, "Curl_parse_port returned error");
ret = curl_url_get(u, CURLUPART_PORT, &portnum, CURLU_NO_DEFAULT_PORT);
fail_unless(ret != CURLUE_OK, "curl_url_get portnum returned something");
@@ -69,7 +69,7 @@ UNITTEST_START
ipv6port = strdup("[fe80::250:56ff:fea7:da15|");
if(!ipv6port)
goto fail;
- ret = Curl_parse_port(u, ipv6port);
+ ret = Curl_parse_port(u, ipv6port, FALSE);
fail_unless(ret != CURLUE_OK, "Curl_parse_port true on error");
free_and_clear(ipv6port);
curl_url_cleanup(u);
@@ -80,7 +80,7 @@ UNITTEST_START
ipv6port = strdup("[fe80::250:56ff;fea7:da15]:80");
if(!ipv6port)
goto fail;
- ret = Curl_parse_port(u, ipv6port);
+ ret = Curl_parse_port(u, ipv6port, FALSE);
fail_unless(ret != CURLUE_OK, "Curl_parse_port true on error");
free_and_clear(ipv6port);
curl_url_cleanup(u);
@@ -92,7 +92,7 @@ UNITTEST_START
ipv6port = strdup("[fe80::250:56ff:fea7:da15%25eth3]:80");
if(!ipv6port)
goto fail;
- ret = Curl_parse_port(u, ipv6port);
+ ret = Curl_parse_port(u, ipv6port, FALSE);
fail_unless(ret == CURLUE_OK, "Curl_parse_port returned error");
ret = curl_url_get(u, CURLUPART_PORT, &portnum, 0);
fail_unless(ret == CURLUE_OK, "curl_url_get portnum returned error");
@@ -108,7 +108,7 @@ UNITTEST_START
ipv6port = strdup("[fe80::250:56ff:fea7:da15%25eth3]");
if(!ipv6port)
goto fail;
- ret = Curl_parse_port(u, ipv6port);
+ ret = Curl_parse_port(u, ipv6port, FALSE);
fail_unless(ret == CURLUE_OK, "Curl_parse_port returned error");
free_and_clear(ipv6port);
curl_url_cleanup(u);
@@ -120,7 +120,7 @@ UNITTEST_START
ipv6port = strdup("[fe80::250:56ff:fea7:da15]:81");
if(!ipv6port)
goto fail;
- ret = Curl_parse_port(u, ipv6port);
+ ret = Curl_parse_port(u, ipv6port, FALSE);
fail_unless(ret == CURLUE_OK, "Curl_parse_port returned error");
ret = curl_url_get(u, CURLUPART_PORT, &portnum, 0);
fail_unless(ret == CURLUE_OK, "curl_url_get portnum returned error");
@@ -136,7 +136,7 @@ UNITTEST_START
ipv6port = strdup("[fe80::250:56ff:fea7:da15];81");
if(!ipv6port)
goto fail;
- ret = Curl_parse_port(u, ipv6port);
+ ret = Curl_parse_port(u, ipv6port, FALSE);
fail_unless(ret != CURLUE_OK, "Curl_parse_port true on error");
free_and_clear(ipv6port);
curl_url_cleanup(u);
@@ -147,19 +147,20 @@ UNITTEST_START
ipv6port = strdup("[fe80::250:56ff:fea7:da15]80");
if(!ipv6port)
goto fail;
- ret = Curl_parse_port(u, ipv6port);
+ ret = Curl_parse_port(u, ipv6port, FALSE);
fail_unless(ret != CURLUE_OK, "Curl_parse_port true on error");
free_and_clear(ipv6port);
curl_url_cleanup(u);
- /* Valid IPv6 with no port after the colon, should use default */
+ /* Valid IPv6 with no port after the colon, should use default if a scheme
+ was used in the URL */
u = curl_url();
if(!u)
goto fail;
ipv6port = strdup("[fe80::250:56ff:fea7:da15]:");
if(!ipv6port)
goto fail;
- ret = Curl_parse_port(u, ipv6port);
+ ret = Curl_parse_port(u, ipv6port, TRUE);
fail_unless(ret == CURLUE_OK, "Curl_parse_port returned error");
free_and_clear(ipv6port);
curl_url_cleanup(u);
@@ -171,7 +172,7 @@ UNITTEST_START
ipv6port = strdup("[fe80::250:56ff:fea7:da15!25eth3]:80");
if(!ipv6port)
goto fail;
- ret = Curl_parse_port(u, ipv6port);
+ ret = Curl_parse_port(u, ipv6port, FALSE);
fail_unless(ret != CURLUE_OK, "Curl_parse_port returned non-error");
free_and_clear(ipv6port);
curl_url_cleanup(u);
@@ -183,10 +184,25 @@ UNITTEST_START
ipv6port = strdup("[fe80::250:56ff:fea7:da15%eth3]:80");
if(!ipv6port)
goto fail;
- ret = Curl_parse_port(u, ipv6port);
+ ret = Curl_parse_port(u, ipv6port, FALSE);
fail_unless(ret == CURLUE_OK, "Curl_parse_port returned error");
+ free_and_clear(ipv6port);
+ curl_url_cleanup(u);
+
+ /* No scheme and no digits following the colon - not accepted. Because that
+ makes (a*50):// that looks like a scheme be an acceptable input. */
+ u = curl_url();
+ if(!u)
+ goto fail;
+ ipv6port = strdup("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaa:");
+ if(!ipv6port)
+ goto fail;
+ ret = Curl_parse_port(u, ipv6port, FALSE);
+ fail_unless(ret == CURLUE_BAD_PORT_NUMBER, "Curl_parse_port did wrong");
fail:
free(ipv6port);
curl_url_cleanup(u);
+
}
UNITTEST_STOP
diff --git a/tests/unit/unit1654.c b/tests/unit/unit1654.c
index 79e97631c..667551ce9 100644
--- a/tests/unit/unit1654.c
+++ b/tests/unit/unit1654.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -36,11 +36,10 @@ unit_stop(void)
curl_global_cleanup();
}
-#if defined(CURL_DISABLE_HTTP) || !defined(USE_ALTSVC)
+#if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_ALTSVC)
UNITTEST_START
{
- return 0; /* nothing to do when HTTP is disabled or alt-svc support is
- missing */
+ return 0; /* nothing to do when HTTP or alt-svc is disabled */
}
UNITTEST_STOP
#else
@@ -54,9 +53,10 @@ UNITTEST_START
return 1;
result = Curl_altsvc_load(asi, arg);
if(result) {
- Curl_altsvc_cleanup(asi);
+ Curl_altsvc_cleanup(&asi);
return result;
}
+ curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if(!curl)
goto fail;
@@ -111,7 +111,7 @@ UNITTEST_START
result =
Curl_altsvc_parse(curl, asi,
"h2=\":443\", h3=\":443\"; ma = 120; persist = 1\r\n",
- ALPN_h1, "curl.haxx.se", 80);
+ ALPN_h1, "curl.se", 80);
if(result) {
fprintf(stderr, "Curl_altsvc_parse(5) failed!\n");
unitfail++;
@@ -120,7 +120,7 @@ UNITTEST_START
/* clear that one again and decrease the counter */
result = Curl_altsvc_parse(curl, asi, "clear;\r\n",
- ALPN_h1, "curl.haxx.se", 80);
+ ALPN_h1, "curl.se", 80);
if(result) {
fprintf(stderr, "Curl_altsvc_parse(6) failed!\n");
unitfail++;
@@ -130,8 +130,9 @@ UNITTEST_START
Curl_altsvc_save(curl, asi, outname);
curl_easy_cleanup(curl);
+ curl_global_cleanup();
fail:
- Curl_altsvc_cleanup(asi);
+ Curl_altsvc_cleanup(&asi);
return unitfail;
}
UNITTEST_STOP
diff --git a/tests/unit/unit1655.c b/tests/unit/unit1655.c
index 1b910ed9f..1d7880d58 100644
--- a/tests/unit/unit1655.c
+++ b/tests/unit/unit1655.c
@@ -9,7 +9,7 @@
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
diff --git a/tests/unit/unit1660.c b/tests/unit/unit1660.c
new file mode 100644
index 000000000..3e9b1a40e
--- /dev/null
+++ b/tests/unit/unit1660.c
@@ -0,0 +1,171 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curlcheck.h"
+
+#include "urldata.h"
+#include "hsts.h"
+
+static CURLcode
+unit_setup(void)
+{
+ return CURLE_OK;
+}
+
+static void
+unit_stop(void)
+{
+ curl_global_cleanup();
+}
+
+#if defined(CURL_DISABLE_HTTP) || !defined(USE_HSTS)
+UNITTEST_START
+{
+ return 0; /* nothing to do when HTTP or HSTS are disabled */
+}
+UNITTEST_STOP
+#else
+
+struct testit {
+ const char *host;
+ const char *chost; /* if non-NULL, use to lookup with */
+ const char *hdr; /* if NULL, just do the lookup */
+ const CURLcode result; /* parse result */
+};
+
+static const struct testit headers[] = {
+ /* two entries read from disk cache, verify first */
+ { "-", "readfrom.example", NULL, CURLE_OK},
+ { "-", "old.example", NULL, CURLE_OK},
+ /* delete the remaining one read from disk */
+ { "readfrom.example", NULL, "max-age=\"0\"", CURLE_OK},
+
+ { "example.com", NULL, "max-age=\"31536000\"\r\n", CURLE_OK },
+ { "example.com", NULL, "max-age=\"21536000\"\r\n", CURLE_OK },
+ { "example.com", NULL, "max-age=\"21536000\"; \r\n", CURLE_OK },
+ { "example.com", NULL, "max-age=\"21536000\"; includeSubDomains\r\n",
+ CURLE_OK },
+ { "example.org", NULL, "max-age=\"31536000\"\r\n", CURLE_OK },
+ { "this.example", NULL, "max=\"31536\";", CURLE_BAD_FUNCTION_ARGUMENT },
+ { "this.example", NULL, "max-age=\"31536", CURLE_BAD_FUNCTION_ARGUMENT },
+ { "this.example", NULL, "max-age=31536\"", CURLE_OK },
+ /* max-age=0 removes the entry */
+ { "this.example", NULL, "max-age=0", CURLE_OK },
+ { "another.example", NULL, "includeSubDomains; ",
+ CURLE_BAD_FUNCTION_ARGUMENT },
+
+ /* Two max-age is illegal */
+ { "example.com", NULL,
+ "max-age=\"21536000\"; includeSubDomains; max-age=\"3\";",
+ CURLE_BAD_FUNCTION_ARGUMENT },
+ /* Two includeSubDomains is illegal */
+ { "2.example.com", NULL,
+ "max-age=\"21536000\"; includeSubDomains; includeSubDomains;",
+ CURLE_BAD_FUNCTION_ARGUMENT },
+ /* use a unknown directive "include" that should be ignored */
+ { "3.example.com", NULL, "max-age=\"21536000\"; include; includeSubDomains;",
+ CURLE_OK },
+ /* remove the "3.example.com" one, should still match the example.com */
+ { "3.example.com", NULL, "max-age=\"0\"; includeSubDomains;",
+ CURLE_OK },
+ { "-", "foo.example.com", NULL, CURLE_OK},
+ { "-", "foo.xample.com", NULL, CURLE_OK},
+
+ /* should not match */
+ { "example.net", "forexample.net", "max-age=\"31536000\"\r\n", CURLE_OK },
+
+ /* should not match either, since forexample.net is not in the example.net
+ domain */
+ { "example.net", "forexample.net",
+ "max-age=\"31536000\"; includeSubDomains\r\n", CURLE_OK },
+ /* remove example.net again */
+ { "example.net", NULL, "max-age=\"0\"; includeSubDomains\r\n", CURLE_OK },
+
+ /* make this live for 7 seconds */
+ { "expire.example", NULL, "max-age=\"7\"\r\n", CURLE_OK },
+ { NULL, NULL, NULL, 0 }
+};
+
+static void showsts(struct stsentry *e, const char *chost)
+{
+ if(!e)
+ printf("'%s' is not HSTS\n", chost);
+ else {
+ printf("%s [%s]: %" CURL_FORMAT_CURL_OFF_T "%s\n",
+ chost, e->host, e->expires,
+ e->includeSubDomains ? " includeSubDomains" : "");
+ }
+}
+
+UNITTEST_START
+{
+ CURLcode result;
+ struct stsentry *e;
+ struct hsts *h = Curl_hsts_init();
+ int i;
+ const char *chost;
+ CURL *easy;
+ if(!h)
+ return 1;
+ easy = curl_easy_init();
+ if(!easy)
+ return 1;
+
+ Curl_hsts_loadfile(easy, h, "log/input1660");
+
+ for(i = 0; headers[i].host ; i++) {
+ if(headers[i].hdr) {
+ result = Curl_hsts_parse(h, headers[i].host, headers[i].hdr);
+
+ if(result != headers[i].result) {
+ fprintf(stderr, "Curl_hsts_parse(%s) failed: %d\n",
+ headers[i].hdr, result);
+ unitfail++;
+ continue;
+ }
+ else if(result) {
+ printf("Input %u: error %d\n", i, (int) result);
+ continue;
+ }
+ }
+
+ chost = headers[i].chost ? headers[i].chost : headers[i].host;
+ e = Curl_hsts(h, chost, TRUE);
+ showsts(e, chost);
+ }
+
+ printf("Number of entries: %zu\n", h->list.size);
+
+ /* verify that it is exists for 7 seconds */
+ chost = "expire.example";
+ for(i = 100; i < 110; i++) {
+ e = Curl_hsts(h, chost, TRUE);
+ showsts(e, chost);
+ deltatime++; /* another second passed */
+ }
+
+ (void)Curl_hsts_save(easy, h, "log/hsts1660");
+ Curl_hsts_cleanup(&h);
+ curl_easy_cleanup(easy);
+ return unitfail;
+}
+UNITTEST_STOP
+#endif
diff --git a/tests/curl_test_data.py.in b/tests/util.py
index 9e21ca122..d79c12f2f 100755
--- a/tests/curl_test_data.py.in
+++ b/tests/util.py
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
@@ -19,13 +19,14 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
-"""Module for extracting test data from the test data folder"""
+"""Module for extracting test data from the test data folder and other utils"""
from __future__ import (absolute_import, division, print_function,
unicode_literals)
+
+import logging
import os
import re
-import logging
log = logging.getLogger(__name__)
@@ -33,6 +34,34 @@ log = logging.getLogger(__name__)
REPLY_DATA = re.compile("<reply>[ \t\n\r]*<data[^<]*>(.*?)</data>", re.MULTILINE | re.DOTALL)
+class ClosingFileHandler(logging.StreamHandler):
+ def __init__(self, filename):
+ super(ClosingFileHandler, self).__init__()
+ self.filename = os.path.abspath(filename)
+ self.setStream(None)
+
+ def emit(self, record):
+ with open(self.filename, "a") as fp:
+ self.setStream(fp)
+ super(ClosingFileHandler, self).emit(record)
+ self.setStream(None)
+
+ def setStream(self, stream):
+ setStream = getattr(super(ClosingFileHandler, self), 'setStream', None)
+ if callable(setStream):
+ return setStream(stream)
+ if stream is self.stream:
+ result = None
+ else:
+ result = self.stream
+ self.acquire()
+ try:
+ self.flush()
+ self.stream = stream
+ finally:
+ self.release()
+ return result
+
class TestData(object):
def __init__(self, data_folder):
self.data_folder = data_folder
diff --git a/tests/valgrind.pm b/tests/valgrind.pm
index 43163bf01..6d457259d 100644
--- a/tests/valgrind.pm
+++ b/tests/valgrind.pm
@@ -9,7 +9,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/tests/valgrind.supp b/tests/valgrind.supp
index 10b07314a..6d72a8bb4 100644
--- a/tests/valgrind.supp
+++ b/tests/valgrind.supp
@@ -1,4 +1,36 @@
{
+ zstd_decompression-1.3.3-on-Ubuntu-18.04
+ Memcheck:Cond
+ fun:ZSTD_decompressStream
+ fun:zstd_unencode_write
+ fun:Curl_unencode_write
+ fun:readwrite_data
+ fun:Curl_readwrite
+ fun:multi_runsingle
+ fun:curl_multi_perform
+ fun:easy_transfer
+ fun:easy_perform
+ fun:curl_easy_perform
+ fun:serial_transfers
+ fun:run_all_transfers
+ fun:operate
+ fun:main
+}
+
+{
+ zstd_decompression-1.3.3-on-Ubuntu-18.04-nondebug
+ Memcheck:Cond
+ fun:ZSTD_decompressStream
+ fun:zstd_unencode_write
+ fun:Curl_readwrite
+ fun:multi_runsingle
+ fun:curl_multi_perform
+ fun:curl_easy_perform
+ fun:operate
+ fun:main
+}
+
+{
libidn-idna_to_ascii-error
Memcheck:Addr4
fun:idna_to_ascii_4z
diff --git a/tests/version-scan.pl.in b/tests/version-scan.pl.in
index 7c56d0501..c466d1a58 100755
--- a/tests/version-scan.pl.in
+++ b/tests/version-scan.pl.in
@@ -10,7 +10,7 @@
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
diff --git a/winbuild/README.md b/winbuild/README.md
new file mode 100644
index 000000000..2475c9885
--- /dev/null
+++ b/winbuild/README.md
@@ -0,0 +1,132 @@
+# Building curl with Visual C++
+
+ This document describes how to compile, build and install curl and libcurl
+ from sources using the Visual C++ build tool. To build with VC++, you will of
+ course have to first install VC++. The minimum required version of VC is 6
+ (part of Visual Studio 6). However using a more recent version is strongly
+ recommended.
+
+ VC++ is also part of the Windows Platform SDK. You do not have to install the
+ full Visual Studio or Visual C++ if all you want is to build curl.
+
+ The latest Platform SDK can be downloaded freely from [Windows SDK and
+ emulator
+ archive](https://developer.microsoft.com/en-us/windows/downloads/sdk-archive)
+
+## Prerequisites
+
+ If you wish to support zlib, openssl, c-ares, ssh2, you will have to download
+ them separately and copy them to the deps directory as shown below:
+
+ somedirectory\
+ |_curl-src
+ | |_winbuild
+ |
+ |_deps
+ |_ lib
+ |_ include
+ |_ bin
+
+ It is also possible to create the deps directory in some other random places
+ and tell the Makefile its location using the WITH_DEVEL option.
+
+## Building straight from git
+
+ When you check out code git and build it, as opposed from a released source
+ code archive, you need to first run the `buildconf.bat` batch file (present
+ in the source code root directory) to set things up.
+
+## Open a command prompt
+
+Open a Visual Studio Command prompt:
+
+ Using the **'Developer Command Prompt for VS [version]'** menu entry: where
+ [version} is the Visual Studio version. The developer prompt at default uses
+ the x86 mode. It is required to call `Vcvarsall.bat` to setup the prompt for
+ the machine type you want. This type of command prompt may not exist in all
+ Visual Studio versions.
+
+ See also: [Developer Command Prompt for Visual
+ Studio](https://docs.microsoft.com/en-us/dotnet/framework/tools/developer-command-prompt-for-vs)
+ and [How to: Enable a 64-Bit, x64 hosted MSVC toolset on the command
+ line](https://docs.microsoft.com/en-us/cpp/build/how-to-enable-a-64-bit-visual-cpp-toolset-on-the-command-line)
+
+ Using the **'VS [version] [platform] [type] Command Prompt'** menu entry:
+ where [version] is the Visual Studio version, [platform] is e.g. x64 and
+ [type] Native of Cross platform build. This type of command prompt may not
+ exist in all Visual Studio versions.
+
+ See also: [Set the Path and Environment Variables for Command-Line Builds](https://msdn.microsoft.com/en-us/library/f2ccy3wt.aspx)
+
+## Build in the console
+
+ Once you are in the console, go to the winbuild directory in the Curl
+ sources:
+
+ cd curl-src\winbuild
+
+ Then you can call `nmake /f Makefile.vc` with the desired options (see
+ below). The builds will be in the top src directory, `builds\` directory, in
+ a directory named using the options given to the nmake call.
+
+ nmake /f Makefile.vc mode=<static or dll> <options>
+
+where `<options>` is one or many of:
+
+ - `VC=<6,7,8,9,10,11,12,14,15>` - VC version
+ - `WITH_DEVEL=<path>` - Paths for the development files (SSL, zlib, etc.)
+ Defaults to sibbling directory deps: ../deps
+ Libraries can be fetched at https://windows.php.net/downloads/php-sdk/deps/
+ Uncompress them into the deps folder.
+ - `WITH_SSL=<dll/static>` - Enable OpenSSL support, DLL or static
+ - `WITH_NGHTTP2=<dll/static>` - Enable HTTP/2 support, DLL or static
+ - `WITH_MBEDTLS=<dll/static>` - Enable mbedTLS support, DLL or static
+ - `WITH_CARES=<dll/static>` - Enable c-ares support, DLL or static
+ - `WITH_ZLIB=<dll/static>` - Enable zlib support, DLL or static
+ - `WITH_SSH2=<dll/static>` - Enable libSSH2 support, DLL or static
+ - `WITH_PREFIX=<dir>` - Where to install the build
+ - `ENABLE_SSPI=<yes/no>` - Enable SSPI support, defaults to yes
+ - `ENABLE_IPV6=<yes/no>` - Enable IPv6, defaults to yes
+ - `ENABLE_IDN=<yes or no>` - Enable use of Windows IDN APIs, defaults to yes
+ Requires Windows Vista or later
+ - `ENABLE_SCHANNEL=<yes/no>` - Enable native Windows SSL support, defaults
+ to yes if SSPI and no other SSL library
+ - `ENABLE_OPENSSL_AUTO_LOAD_CONFIG=<yes/no>`
+ - Enable loading OpenSSL configuration
+ automatically, defaults to yes
+ - `ENABLE_UNICODE=<yes/no>` - Enable UNICODE support, defaults to no
+ - `GEN_PDB=<yes/no>` - Generate Program Database (debug symbols for release build)
+ - `DEBUG=<yes/no>` - Debug builds
+ - `MACHINE=<x86/x64>` - Target architecture (default is x86)
+ - `CARES_PATH=<path>` - Custom path for c-ares
+ - `MBEDTLS_PATH=<path>` - Custom path for mbedTLS
+ - `NGHTTP2_PATH=<path>` - Custom path for nghttp2
+ - `SSH2_PATH=<path>` - Custom path for libSSH2
+ - `SSL_PATH=<path>` - Custom path for OpenSSL
+ - `ZLIB_PATH=<path>` - Custom path for zlib
+
+## Static linking of Microsoft's C RunTime (CRT):
+
+ If you are using mode=static nmake will create and link to the static build
+ of libcurl but *not* the static CRT. If you must you can force nmake to link
+ in the static CRT by passing RTLIBCFG=static. Typically you shouldn't use
+ that option, and nmake will default to the DLL CRT. RTLIBCFG is rarely used
+ and therefore rarely tested. When passing RTLIBCFG for a configuration that
+ was already built but not with that option, or if the option was specified
+ differently, you must destroy the build directory containing the
+ configuration so that nmake can build it from scratch.
+
+## Building your own application with a static libcurl
+
+ When building an application that uses the static libcurl library on Windows,
+ you must define CURL_STATICLIB. Otherwise the linker will look for dynamic
+ import symbols.
+
+## Legacy Windows and SSL
+
+ When you build curl using the build files in this directory the default SSL
+ backend will be Schannel (Windows SSPI), the native SSL library that comes
+ with the Windows OS. Schannel in Windows <= XP is not able to connect to
+ servers that no longer support the legacy handshakes and algorithms used by
+ those versions. If you will be using curl in one of those earlier versions of
+ Windows you should choose another SSL backend like OpenSSL.