Message from discussion
WebSockets is very faster than xhr. I hope to support of jQuery for WebSockets.
X-BeenThere: jquery-dev@googlegroups.com
Received: by 10.229.68.219 with SMTP id w27ls36305qci.2.p; Tue, 19 Jan 2010
21:37:10 -0800 (PST)
Received: by 10.229.127.80 with SMTP id f16mr1256943qcs.25.1263965830204;
Tue, 19 Jan 2010 21:37:10 -0800 (PST)
Received: by 10.229.127.80 with SMTP id f16mr1256941qcs.25.1263965830035;
Tue, 19 Jan 2010 21:37:10 -0800 (PST)
Return-Path: <s...@sidneysm.com>
Received: from mail-qy0-f177.google.com (mail-qy0-f177.google.com [209.85.221.177])
by gmr-mx.google.com with ESMTP id 25si2444856qyk.7.2010.01.19.21.37.09;
Tue, 19 Jan 2010 21:37:09 -0800 (PST)
Received-SPF: neutral (google.com: 209.85.221.177 is neither permitted nor denied by best guess record for domain of s...@sidneysm.com) client-ip=209.85.221.177;
Authentication-Results: gmr-mx.google.com; spf=neutral (google.com: 209.85.221.177 is neither permitted nor denied by best guess record for domain of s...@sidneysm.com) smtp.mai...@sidneysm.com
Received: by mail-qy0-f177.google.com with SMTP id 7so2558927qyk.10
for <jquery-dev@googlegroups.com>; Tue, 19 Jan 2010 21:37:09 -0800 (PST)
Received: by 10.224.84.13 with SMTP id h13mr2363783qal.230.1263965829594;
Tue, 19 Jan 2010 21:37:09 -0800 (PST)
Return-Path: <s...@sidneysm.com>
Received: from sidney-mbp.lan (pool-96-242-53-128.nwrknj.fios.verizon.net [96.242.53.128])
by mx.google.com with ESMTPS id 8sm7786291qwj.43.2010.01.19.21.37.07
(version=TLSv1/SSLv3 cipher=RC4-MD5);
Tue, 19 Jan 2010 21:37:08 -0800 (PST)
From: =?iso-8859-1?Q?Sidney_San_Mart=EDn?= <s...@sidneysm.com>
Mime-Version: 1.0 (Apple Message framework v1077)
Content-Type: multipart/signed; boundary=Apple-Mail-1-43301233; protocol="application/pkcs7-signature"; micalg=sha1
Subject: Re: [jquery-dev] Re: WebSockets is very faster than xhr. I hope to support of jQuery for WebSockets.
Date: Wed, 20 Jan 2010 00:37:06 -0500
In-Reply-To: <cd3ce1c2-76da-4f46-8fed-9b5ddfe437a0@u41g2000yqe.googlegroups.com>
To: jquery-dev@googlegroups.com
References: <bf504415-ea36-4ca0-8179-e8b5886e4...@c29g2000yqd.googlegroups.com> <4B549A16.3010...@gmail.com> <deff46d6-bddd-4b29-bb30-6c9516172...@l30g2000yqb.googlegroups.com> <4B55F569.6050...@gmail.com> <cd3ce1c2-76da-4f46-8fed-9b5ddfe43...@u41g2000yqe.googlegroups.com>
Message-Id: <7F71EA0C-BD43-40BB-B931-835B5B1BE...@sidneysm.com>
X-Mailer: Apple Mail (2.1077)
--Apple-Mail-1-43301233
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset=utf-8
If I'm reading you correctly, jQuery support for Web Sockets would be:
1. Feature detection through jQuery.support
2. Close open sockets on unload
3. Keep up a heartbeat with the server
4. Filter JavaScript from incoming data
5. jQuery-like API for sending and receiving on sockets.
(1) would make sense only if there were other support in jQuery, (2) is =
handled by the UA, (3) is protocol-dependent and I'm not sure is even =
necessary, (4) depends on what you're trying to do with data coming out =
of the socket (and data sanitation should be handled by the server in =
most cases). (5) is a different question entirely.
I've definitely seen posts pop up on discussion boards and mailing lists =
asking "how can I rewrite such-and-such JavaScript in jQuery?" While
if (typeof WebSocket =3D=3D=3D 'object') {
socket =3D new WebSocket('ws://example.com');
socket.onmessage =3D handleMessage;
}
doesn't fit in with existing jQuery code as well as
if ($.support.sockets) {
socket =3D $.socket('ws://example.com').receive(handleMessage);
}
should anyone care? I don't know. The jQuery object always represents a =
collection of DOM elements because jQuery has always been about talking =
to the DOM.
On the other hand, with JSON-encoded responses $.ajax succeeds in =
turning XMLHTTPRequest into a tube that you can shove objects and arrays =
into and get same back. That's solidly outside DOM territory but is a =
well-worn jQuery feature. Automagic response parsing into native types =
could work for Web Sockets as well.
There are more wild and interesting things that *could* be done by =
abstracting a bit =E2=80=94 like the framework maintaining a single =
socket to your app and triggering custom event handlers based on =
metadata in messages =E2=80=94 but it's still way to early to suggest =
putting any of that in jQuery proper. If you want to live on the =
bleeding edge, write some code. Sanding down the API can come once we =
know what the heck we want it to look like.
On Jan 19, 2010, at 10:00 PM, tato wrote:
> Hi Friesen
>=20
> Your code is yes. Please try following.
>=20
> <input type=3D"text" id=3D"test" value=3D"hello!">
> <button =
onclick=3D"ws.send(document.getElementById('test').value)">send</
> button>
>=20
> <script>
> var ws =3D new WebSocket("ws://bloga.jp:80/echo");
> ws.onmessage =3D function(msg) {
> alert(msg.data)
> };
> </script>
>=20
> You send 'hi!', You'll receive 'hi!'
> If You send 'Goodbye', then see TCP Packet, You'll receive
> Connection: close
>=20
> eg.
>=20
> GET /echo HTTP/1.1=EF=BD=A5=EF=BD=A5Upgrade: =
WebSocket=EF=BD=A5=EF=BD=A5Connection: Upgrade=EF=BD=A5=EF=BD=A5Host:
> bloga.jp=EF=BD=A5=EF=BD=A5Origin: file://=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=
=A5=EF=BD=A5=EF=BD=A5
> tcp 202.215.119.36:80 > 192.168.1.10:1032
> ( omit )
> tcp 192.168.1.10:4964 > 202.215.119.36:80
> =
=EF=BD=A5hi!=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=
=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=
=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=
=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=
=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=
=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=
=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5
> tcp 202.215.119.36:80 > 192.168.1.10:4964
> =
=EF=BD=A5hi!=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=
=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=
=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=
=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=
=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=
=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=
=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5
> tcp 192.168.1.10:4942 > 202.215.119.36:80
> =
=EF=BD=A5Goodbye=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=
=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=
=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=
=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=
=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=
=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=
=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5
> tcp 202.215.119.36:80 > 192.168.1.10:4942
> =
=EF=BD=A5Goodbye=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=
=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=
=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=
=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=
=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=
=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=
=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5
> tcp 202.215.119.36:80 > 192.168.1.10:4942
> HTTP/1.1 200 OK=EF=BD=A5=EF=BD=A5Date: Wed, 20 Jan 2010 00:16:04 =
GMT=EF=BD=A5=EF=BD=A5Server: Apache/
> 2.2.12 (Ubuntu)=EF=BD=A5=EF=BD=A5Content-Length: 0=EF=BD=A5=EF=BD=A5Conn=
ection: close=EF=BD=A5=EF=BD=A5Cont
> ent-Type: =
text/plain=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=
=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=
=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=
=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=
=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5
>=20
> This "ws://bloga.jp:80/echo" is a echo server of mod_pywebsocket's
> sample.
> I have not checked Origin, It will work. if connected to the Internet.
> Even if the local disk.
>=20
>=20
> Well, There are three ways
>=20
> 1.Min support
> 2.Partial support
> 3.Full support
>=20
> I think, case 3:
> create $.websocket like $.ajax
> onunload close,keep alive heatbeat,/<script(.|\s)*?\/
> script>/g, "",nosupport flag etc...
> now, we are looking for tips
> case 2:
> Some methods into the $ or $.fn
> Perhaps many variations
> case 1:
> only create ws object
> eg.
> $.extend({
> ws : function (url){
> if(WebSocket)return new WebSocket(url);
> }
> })
> but, This is so useless, but in the namespace.
>=20
>=20
>=20
>> WS isn't HTTP
>=20
> Yes, it is. Upgrade: WebSocket from HTTP GET.
>=20
> eg.
>=20
> tcp 192.168.1.4:1715 > 202.215.119.36:80
> GET /echo HTTP/1.1=EF=BD=A5=EF=BD=A5Upgrade: =
WebSocket=EF=BD=A5=EF=BD=A5Connection: Upgrade=EF=BD=A5=EF=BD=A5Host:
> bloga.jp=EF=BD=A5=EF=BD=A5Origin: =
file://=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=
=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=
=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=
=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5=EF=BD=
=A5=EF=BD=A5=EF=BD=A5=EF=BD=A5
>=20
>=20
>> You do realize that WS cannot be used in most shared hosting setups?
>=20
> When I started my JavaScript (1996), AddType application/x-
> javascript .js even cannot be used in shared hosting. But, in a few
> years, everywhere
>=20
> I do not know the future, however, if it was useful, I think that
> spread quickly. And perhaps there are advantages to shared hosting
> sever. Because only connection for the server load low. Last week, 40
> in connection load average is 0.00 at Atom CPU Server. Of course a lot
> more testing is required.
>=20
> Thanx
>=20
> On Jan 20, 3:09 am, Daniel Friesen <nadir.seen.f...@gmail.com> wrote:
>> tato wrote:
>>> Thax,
>>=20
>>> First the excuses. This is a discussion about the future.
>>> However, this future is in front of us.
>>=20
>>> Browser's between incompatibility in ajax was need JS Library /
>>> jQuery, and was very helpful. It is, I agree.
>>=20
>>> But even if there is compatibility, jQuery support of xhr is useful.
>>=20
>>> Future browser with WebSockets implemented, I want compatibility
>>> between them.
>>> But I think, even if there is compatibility, jQuery support of ws is
>>> useful too. Rather less code ;-)
>>=20
>> Less code?
>> var ws =3D new WebSocket("ws://example.com");
>> ws.onmessage =3D function(msg) {
>> // ...
>>=20
>> };
>>=20
>> How much shorter can jQuery possibly make that?
>>=20
>>>> WS is a bi-directional non-HTTP socket which needs a dedicated =
server.
>>=20
>>> It's non-HTTP, but it's on-HTTP too.
>>> I think, WS is a real bi-directional on-HTTP shares available =
socket,
>>> isn't it?
>>=20
>>> I tested on mod_pywebsocket, that is a Web Socket extension for =
Apache
>>> HTTP Server. IETF specification is, The Web Socket default port is =
80
>>> or 443.
>>=20
>>> =
http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-44#sectio...
>>> http://code.google.com/p/pywebsocket/
>>> =
http://blog.chromium.org/2009/12/web-sockets-now-available-in-google....
>>=20
>> WS' handshake is HTTP-like. The only "HTTP" in WS is a handshake that
>> immediately upgrades the connection to the WebSocket protocol leaving
>> HTTP behind.
>> WS isn't HTTP, it completely breaks the request-response model of =
HTTP,
>> it just encapsulates itself in HTTP. If WebSockets were HTTP =
websocket
>> urls would be http:// not ws://
>> The purpose of the HTTP handshake iirc is primarily so that existing
>> load balancing technologies, proxy servers like varnish, etc... meant
>> for http can still be used (in pipe mode ignoring contents mostly) =
and
>> also so WS doesn't require another port which is default-blocked in =
most
>> cases.
>>=20
>> You do realize that WS cannot be used in most shared hosting setups?
>> Most shared hosts use apache, which as I recall buffers http
>> requests/responses meaning WS won't work on the other side, and the
>> users obviously can't install new modules. To use WS you need some =
sort
>> of VPS, Cloud server, dedicated server, etc... Anything but a shared =
host.
>> That there is likely a good portion of the jQuery userbase.
>>=20
>>>> WS is simply "faster" because it doesn't need all the extra cruft =
in a
>>=20
>>> HTTP call
>>=20
>>> I think so too. XHR requires a lot of headers, and many connections.
>>> WS is Handshake header 'GET / demo HTTP/1.1 ...', only once.
>>=20
>>> WS is so friendly for network and servers. Moreover, "faster" on =
HTTP.
>>=20
>>> With Best regards, for into the good future
>>=20
>>> On 1=E6=9C=8819=E6=97=A5, =E5=8D=88=E5=89=8D2:27, Daniel Friesen =
<nadir.seen.f...@gmail.com> wrote:
>>=20
>>>> I don't like the idea. At this point there is no reason to believe =
that
>>>> any browser with WebSockets implemented will break spec and need a
>>>> compatibility layer (the primary reason jQuery has ajax). I don't =
see
>>>> how jQuery could add any functionality to WebSockets, the api is =
already
>>>> quite nice, not to mention there are a large number of calls and =
parts
>>>> to the api, so there would be a pile of jQuery code just matching =
up the
>>>> api to make calls you could make without jQuery at all.
>>=20
>>>> In any case, comparing WS to XHR in terms of speed is completely
>>>> pointless. XHR is a way to make a HTTP call from JS. WS is a
>>>> bi-directional non-HTTP socket which needs a dedicated server. They =
have
>>>> completely different purposes and use cases, speed is irrelevant to =
a
>>>> comparison. WS is simply "faster" because it doesn't need all the =
extra
>>>> cruft in a HTTP call and it's an open dedicated connection between =
the
>>>> browser and the server that doesn't close after every message.
>>=20
>>>> ~Daniel Friesen (Dantman, Nadir-Seen-Fire) =
[http://daniel.friesen.name]
>>=20
>>>> ...
>>=20
>> ~Daniel Friesen (Dantman, Nadir-Seen-Fire) =
[http://daniel.friesen.name]
> --=20
> You received this message because you are subscribed to the Google =
Groups "jQuery Development" group.
> To post to this group, send email to jquery-dev@googlegroups.com.
> To unsubscribe from this group, send email to =
jquery-dev+unsubscribe@googlegroups.com.
> For more options, visit this group at =
http://groups.google.com/group/jquery-dev?hl=3Den.
>=20
>=20
--Apple-Mail-1-43301233
Content-Disposition: attachment;
filename=smime.p7s
Content-Type: application/pkcs7-signature;
name=smime.p7s
Content-Transfer-Encoding: base64
MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIVNDCCBMww
ggQ1oAMCAQICEByunWua9OYvIoqj2nRhbB4wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx
FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAxIFB1YmxpYyBQcmltYXJ5
IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA1MTAyODAwMDAwMFoXDTE1MTAyNzIzNTk1OVow
gd0xCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNp
Z24gVHJ1c3QgTmV0d29yazE7MDkGA1UECxMyVGVybXMgb2YgdXNlIGF0IGh0dHBzOi8vd3d3LnZl
cmlzaWduLmNvbS9ycGEgKGMpMDUxHjAcBgNVBAsTFVBlcnNvbmEgTm90IFZhbGlkYXRlZDE3MDUG
A1UEAxMuVmVyaVNpZ24gQ2xhc3MgMSBJbmRpdmlkdWFsIFN1YnNjcmliZXIgQ0EgLSBHMjCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMnfrOfq+PgDFMQAktXBfjbCPO98chXLwKuMPRyV
zm8eECw/AO2XJua2x+atQx0/pIdHR0w+VPhs+Mf8sZ69MHC8l7EDBeqV8a1AxUR6SwWi8mD81zpl
Yu//EHuiVrvFTnAt1qIfPO2wQuhejVchrKaZ2RHp0hoHwHRHQgv8xTTq/ea6JNEdCBU3otdzzwFB
L2OyOj++pRpu9MlKWz2VphW7NQIZ+dTvvI8OcXZZu0u2Ptb8Whb01g6J8kn+bAztFenZiHWcec5g
J925rXXOL3OVekA6hXVJsLjfaLyrzROChRFQo+A8C67AClPN1zBvhTJGG+RJEMJs4q8fef/btLUC
AwEAAaOCAYQwggGAMBIGA1UdEwEB/wQIMAYBAf8CAQAwRAYDVR0gBD0wOzA5BgtghkgBhvhFAQcX
ATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMAsGA1UdDwQEAwIB
BjARBglghkgBhvhCAQEEBAMCAQYwLgYDVR0RBCcwJaQjMCExHzAdBgNVBAMTFlByaXZhdGVMYWJl
bDMtMjA0OC0xNTUwHQYDVR0OBBYEFBF9Xhl9PATfamzWoooaPzHYO5RSMDEGA1UdHwQqMCgwJqAk
oCKGIGh0dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTEuY3JsMIGBBgNVHSMEejB4oWOkYTBfMQsw
CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEgUHVi
bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHmCEQDNun9W8N/kvFT+IqyzcqpVMA0G
CSqGSIb3DQEBBQUAA4GBALEv2ZbhkqLugWDlyCog++FnLNYAmFOjAhvpkEv4GESfD0b3+qD+0x0Y
o9K/HOzWGZ9KTUP4yru+E4BJBd0hczNXwkJavvoAk7LmBDGRTl088HMFN2Prv4NZmP1m3umGMpqS
KTw6rlTaphJRsY/IytNHeObbpR6HBuPRFMDCIfa6MIIFBzCCAu+gAwIBAgIDAIoNMA0GCSqGSIb3
DQEBBQUAMFQxFDASBgNVBAoTC0NBY2VydCBJbmMuMR4wHAYDVQQLExVodHRwOi8vd3d3LkNBY2Vy
dC5vcmcxHDAaBgNVBAMTE0NBY2VydCBDbGFzcyAzIFJvb3QwHhcNMDkwOTA1MDAzNzQ1WhcNMTEw
OTA1MDAzNzQ1WjA7MRowGAYDVQQDExFTaWRuZXkgU2FuIE1hcnRpbjEdMBsGCSqGSIb3DQEJARYO
c0BzaWRuZXlzbS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDUmYL81XYYic0N
N935bL3wVfzshPDygVqxxQ1ZoiqhuAUewBDuoLA/SllYI06PaFgKlPXyHEoLEyhiss+CObhthAtA
k47OPZCD8TZNfv2r+iEWbSUx3kLdsiZVNMPlBbQaejIe2D8bCyw5ecw0pZWkNcqf51jWKlI6qb5y
e7YeNufFYDh+RnJ/JS37LQW9VSWkJLr/fgTBYbdVlynPCvFbcmUpHlfGrguYXLJCABE7ri03ytdy
BUmL5xbm3RPpXhrkTi3XRh96BBVNNBXteg2xZ7D4sIygJrRAg1zOySUU82tYaDmrEVnTbbUczzE+
V051MBw/HL+1hfTdYipBxRVrAgMBAAGjgfowgfcwDAYDVR0TAQH/BAIwADBWBglghkgBhvhCAQ0E
SRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQgb3ZlciB0byBodHRw
Oi8vd3d3LkNBY2VydC5vcmcwQAYDVR0lBDkwNwYIKwYBBQUHAwQGCCsGAQUFBwMCBgorBgEEAYI3
CgMEBgorBgEEAYI3CgMDBglghkgBhvhCBAEwMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZo
dHRwOi8vb2NzcC5jYWNlcnQub3JnMBkGA1UdEQQSMBCBDnNAc2lkbmV5c20uY29tMA0GCSqGSIb3
DQEBBQUAA4ICAQAcMr2LtE8dzvshGIk5lfHOuMci6ijq/7GRVo2XbqZbLPrTTW/vde12LTjp01B2
p9RghngNOtZSpuvC2G9vNRXbx0LR2ABvSic1ZcrkEBrNOe+NGWeQRAaG1o4E2Stm8IWPczcPhThW
fc7dFROatHyf4BuNeuGUq2zhFcf7aGoiPIT/7iEAYzimMKxTYn4Tf9izGcUe0ZrQc+ve/urNAdX5
lqh9XVZbTAdH9WpBCNOmK9OHmugaUL+6e/fo0SpfHengB+T5+cKc6CdpxMkAozFWy839feb6yu5r
s9TbOXbcbHm+tVVK1c4j7/wQDgtjhBNmWpqJSmLD8Fd4g/V5DswSEYs3+as4HiqasDRq6K2uZzEc
CucDb4iLUeDGI5M+vrL2vFzef3UZWIRwBiHap4GzeIS5k4BJiFT67WRF7L2LBEmEt04atSjbHDtR
WQRtUoK1ZvZkzWFekIa8/Npo0Ozb2XVdt2B8CU+6Fkwx+kajVAyaJ31HT8PqgMBxMuq6OC1cSAYp
CB/Zm+4wsAz0g6OKv2189I9/oE4fbrn2Ao2ni2hd0P8Xa116WYh35x/05g0AQ69rYeuNvpMh/TjM
4HMQ59sctoHF07vNaoGRr5xGCFg4ly3jRpmOMjHoNR761mAnK8+9XDd5oX+GV8paxI9dqzRECb61
aXfTZYTEhBDaNDCCBUkwggQxoAMCAQICEDUSM9ZeaTgg29BigNbr6HcwDQYJKoZIhvcNAQEFBQAw
gd0xCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNp
Z24gVHJ1c3QgTmV0d29yazE7MDkGA1UECxMyVGVybXMgb2YgdXNlIGF0IGh0dHBzOi8vd3d3LnZl
cmlzaWduLmNvbS9ycGEgKGMpMDUxHjAcBgNVBAsTFVBlcnNvbmEgTm90IFZhbGlkYXRlZDE3MDUG
A1UEAxMuVmVyaVNpZ24gQ2xhc3MgMSBJbmRpdmlkdWFsIFN1YnNjcmliZXIgQ0EgLSBHMjAeFw0w
OTEwMTcwMDAwMDBaFw0xMDEwMTcyMzU5NTlaMIIBEjEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4x
HzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxRjBEBgNVBAsTPXd3dy52ZXJpc2lnbi5j
b20vcmVwb3NpdG9yeS9SUEEgSW5jb3JwLiBieSBSZWYuLExJQUIuTFREKGMpOTgxHjAcBgNVBAsT
FVBlcnNvbmEgTm90IFZhbGlkYXRlZDEzMDEGA1UECxMqRGlnaXRhbCBJRCBDbGFzcyAxIC0gTmV0
c2NhcGUgRnVsbCBTZXJ2aWNlMRowGAYDVQQDFBFTaWRuZXkgU2FuIE1hcnRpbjEdMBsGCSqGSIb3
DQEJARYOc0BzaWRuZXlzbS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDLnRXo
RDBBgVyJnFkDsvuU7YrP4dOZpUkWaDZ2QvAAaqJ+ZQ9qKx8NlgE1guu5g16ojorsLoUs2xisIqbx
Zw+QWQ/9rPcb0ZizI19Ij7mSRxq+VWSsl2f7pv8Fjt9TH102Exx0U3GbeLT2htUWEodqsdTlttCi
pBoKYazddkCfsx55PQ5nq59074jKbtnUgEvQcrLLdU6xnZsj4ZIlDdlc1o6VZgF9jhELS54GYORw
vrI2Io2RWOkU9yaW21HQKTps8uoFxNX3Ymo4gfZ9Qkt6dqflU55CRoRu6WYR+MVGemuJPZpdWyUg
GmiVDEUhS0mXOVl4IwuhSUuNIsFodb8nAgMBAAGjgcwwgckwCQYDVR0TBAIwADBEBgNVHSAEPTA7
MDkGC2CGSAGG+EUBBxcBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9y
cGEwCwYDVR0PBAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMEBggrBgEFBQcDAjBKBgNVHR8EQzBB
MD+gPaA7hjlodHRwOi8vSW5kQzFEaWdpdGFsSUQtY3JsLnZlcmlzaWduLmNvbS9JbmRDMURpZ2l0
YWxJRC5jcmwwDQYJKoZIhvcNAQEFBQADggEBACOg78Ed2n/XgZW59QuhB6cOs3fOASurN7Ft6gk+
SaQrQYPhhjqPor5k1m8xw01XY3nL3qIUYIxEit9Anftm5i5YYyGKumvnU29AlKRgrBenKq4P0KVw
T12haUxgdigHSLNf79Mr2ZJUewuLb4HgKEM+W5nzvnf1Br+JOH0yRLBrGNs34mZfJqc+DYjWAJnm
0pR95SYbC0ONKhV02etpjHnLYgRCyvqU6WaInJOfZ3tzPib3Hss0g7YGdlcbxMemc5stww/UGOS0
ByLb6Uovx2ToVQEP5d6DCj+zybEJ47AifOPldAH9yU9nMFGJ4sTBt54tQ6kzg5vIqkfNGsgut0ow
ggYIMIID8KADAgECAgEBMA0GCSqGSIb3DQEBBAUAMHkxEDAOBgNVBAoTB1Jvb3QgQ0ExHjAcBgNV
BAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEiMCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhv
cml0eTEhMB8GCSqGSIb3DQEJARYSc3VwcG9ydEBjYWNlcnQub3JnMB4XDTA1MTAxNDA3MzY1NVoX
DTMzMDMyODA3MzY1NVowVDEUMBIGA1UEChMLQ0FjZXJ0IEluYy4xHjAcBgNVBAsTFWh0dHA6Ly93
d3cuQ0FjZXJ0Lm9yZzEcMBoGA1UEAxMTQ0FjZXJ0IENsYXNzIDMgUm9vdDCCAiIwDQYJKoZIhvcN
AQEBBQADggIPADCCAgoCggIBAKtJNRFIfNImflOUz0Op3SjXQiqL84d4GVh8D57aiX3h++tykA10
oZZkq5+gJJlz2uJVdscXe/UErEa4w75/ZI0QbCTzYZzA8pD6Ueb1aQFjww9W4kpCz+JEjCUoqMV5
CX1GuYrz6fM0KQhF5Byfy5QEHIGoFLOYZcRD7E6CjQnRvapbjZLQ7N6QxX8KwuPr5jFaXnQ+lzNZ
6MMDPWAzv/fRb0fEze5ig1JuLgiapNkVGJGmhZJHsK5I6223IeyFGmhyNav/8BBdwPSUp2rVO5J+
TJAFfpPBLIukjmJ0FXFuC3ED6q8VOJrU0gVyb4z5K+taciX5OUbjchs+BMNkJyIQKopPWKcDrb60
LhPtXapI19V91Cp7XPpGBFDkzA5CW4zt2/LP/JaT4NsRNlRiNDiPDGCbO5dWOK3z0luLoFvqTpa4
fNfVoIZwQNORKbeiPK31jLvPGpKK5DR7wNhsX+kKwsOnIJpa3yxdUly6R9Wb7yQocDggL9V/KcCy
QQNokszgnMyXS0XvOhAKq3A6mJVwrTWx6oUrpByAITGprmB6gCZIALgBwJNjVSKRPFbnr9s6JfOP
MVTqJouBWfmh0VMRxXudA/Z0EeBtsSw/LIaRmXGapneLNGDRFLQsrJ2vjBDTn8Rq+G8T/HNZ92ZC
dB6K4/jc0m+YnMtHmJVABfvpAgMBAAGjgb8wgbwwDwYDVR0TAQH/BAUwAwEB/zBdBggrBgEFBQcB
AQRRME8wIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLkNBY2VydC5vcmcvMCgGCCsGAQUFBzAChhxo
dHRwOi8vd3d3LkNBY2VydC5vcmcvY2EuY3J0MEoGA1UdIARDMEEwPwYIKwYBBAGBkEowMzAxBggr
BgEFBQcCARYlaHR0cDovL3d3dy5DQWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDANBgkqhkiG9w0B
AQQFAAOCAgEAfwiIodoaUEnaifuhCHLzivcexDq0eVsgMLFF3sJd02Vp8cJdVFQ8hV+5e0KRwpn9
G1Gbq0aloRBTnm2IrHNuLDOm8PSe4HXBPohFqeFmQ/5WWtF6QXj3QNpKOvELW6W7FgbmwueTuYVN
l0+xHjhDgO+bDYzvuKdgAIdXfR5EHMsj75s8mZ2vtSkcRXkWlk0nbfEcbMPCVWSzvBTi86QfHjL8
JxUFz90urj6CYXvwIRAY9kTqUzn53NCaIODGu+C7Wk/EmcgHvbW9otsuYg1CNEG8/4uK9VEiqogw
AOKw1Ly+ZbrVA1d5m+jcyE34UO2RpVIooqz7Nlg+6ZQrkVCHG9Ze1ozM9w8QDFJO0BZh5eUKbL8X
x3JGV5yY9WxgY3pvXrlOL8i5ubtqhbyYDe35PpeENJSuAK+h5eeSbk698+LZFItc0usBbKAXpS0Q
65x6Sr297s797SJAq3A4iPUKh2rCqwVgyUgF2lPB3kR3arPzPDztgLymOEopJF/+WTubJXpWYwBk
uV2kYn1XNk+tg+8fklOgjndX3eVhET0jAJBMPPqjYJMEo6819g5qj09KYKeFBWxGoY/0x3bjoVlX
93GyxG4UXG1tQWbfG5Ox1ADD7svPPD0hgKlfY2X83eBfpPQr8IVxQdRnJfsasZeu1pmCE0HSbqUb
mSeA5wupqAAxggNVMIIDUQIBATCB8jCB3TELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWdu
LCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBv
ZiB1c2UgYXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNTEeMBwGA1UECxMVUGVy
c29uYSBOb3QgVmFsaWRhdGVkMTcwNQYDVQQDEy5WZXJpU2lnbiBDbGFzcyAxIEluZGl2aWR1YWwg
U3Vic2NyaWJlciBDQSAtIEcyAhA1EjPWXmk4INvQYoDW6+h3MAkGBSsOAwIaBQCgggE3MBgGCSqG
SIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTEwMDEyMDA1MzcwNlowIwYJKoZI
hvcNAQkEMRYEFOKDua3U+uuhf71Ncf/o4GAQbhefMGoGCSsGAQQBgjcQBDFdMFswVDEUMBIGA1UE
ChMLQ0FjZXJ0IEluYy4xHjAcBgNVBAsTFWh0dHA6Ly93d3cuQ0FjZXJ0Lm9yZzEcMBoGA1UEAxMT
Q0FjZXJ0IENsYXNzIDMgUm9vdAIDAIoNMGwGCyqGSIb3DQEJEAILMV2gWzBUMRQwEgYDVQQKEwtD
QWNlcnQgSW5jLjEeMBwGA1UECxMVaHR0cDovL3d3dy5DQWNlcnQub3JnMRwwGgYDVQQDExNDQWNl
cnQgQ2xhc3MgMyBSb290AgMAig0wDQYJKoZIhvcNAQEBBQAEggEAdEvhePsnv5H0x06QVXiQlTnr
wAoDZQ5M+UlEftj2SUzEAThXrUZdpSo7EuBw/JsczqDbcD3jwG1E/sNiYUIwbz/C/0azY/QuFLlU
f+7qiLisxn6UTd2pA48va3cPe2XZOYcYHcvnNiw+ulv6rI9TFVlLExrSkwee2PPj0964Geke0qLC
sebgUTPFnLLAHPTcCobOZdN/acLO/V9qT+E+Inu92NdvmC2p9+AETZNE4Bn733h5pShbI5JiYjEW
Wu6eQ4ZB7OPqsWcNm6wS4mnD9yYxoA/FUh/wnjexyiqoRPQNdQURPmkW8OFNYxm7h7RWRUOuuluC
GjQ8Lx946vQxUgAAAAAAAA==
--Apple-Mail-1-43301233--