From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: *** X-Spam-Status: No, score=3.7 required=5.0 tests=AWL,DNS_FROM_RFC_POST, HTML_MESSAGE,MIME_BASE64_TEXT,SPF_NEUTRAL autolearn=disabled version=3.1.3 Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by yquem.inria.fr (Postfix) with ESMTP id C6C59BBAF for ; Mon, 1 Jun 2009 13:34:49 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AswCAP9ZI0pKfS4fjWdsb2JhbACCUoswiG4BaD8BAQEBCQkKCQ8Fok0IgQyODwEDAgSECAWGPQ X-IronPort-AV: E=Sophos;i="4.41,283,1241388000"; d="scan'208";a="28637878" Received: from yw-out-2324.google.com ([74.125.46.31]) by mail3-smtp-sop.national.inria.fr with ESMTP; 01 Jun 2009 13:34:48 +0200 Received: by yw-out-2324.google.com with SMTP id 9so4014286ywe.3 for ; Mon, 01 Jun 2009 04:34:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:reply-to:in-reply-to :references:date:message-id:subject:from:to:cc:content-type; bh=prtxzuUMLmh6zLqGd8+Hh7B9uT+JXPyuJDVj5xKKTsQ=; b=cQ53y7V+IMu5afqxN9qpo47DmXy03SS1jJkxJ4WT8SDla8IIcPpu1K+Ip/opdP4hy3 iWusIrQVkW8EYPRkB5Nx4K0Gw0JLqjd4xfyIkS/weTbpUqYk/bhd54RXxxhuHXgcqFJ7 Fdczn4yxP4Z0v5fdcJFEWNk0Z6x3GezVhsiVA= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:reply-to:in-reply-to:references:date:message-id :subject:from:to:cc:content-type; b=UDzW1KiCWHT5RhYMbkeHPzNWm4KUbBjRlnSEuDtNyaUuPa/wcPuVdqkGurFoW5D1dw CRbGxse+Fg4ICHmJsDkGmxVvedIlnOisCoDZrepQTqsmikSYDejn6Xhbi2ptgPIB/bOO OCrWg9fzKWfdM01PH1N3/iSJwhvO3LICaYI1Q= MIME-Version: 1.0 Received: by 10.90.26.3 with SMTP id 3mr5169094agz.49.1243856087912; Mon, 01 Jun 2009 04:34:47 -0700 (PDT) Reply-To: yminsky@gmail.com In-Reply-To: <411083.97835.qm@web111504.mail.gq1.yahoo.com> References: <411083.97835.qm@web111504.mail.gq1.yahoo.com> Date: Mon, 1 Jun 2009 07:34:47 -0400 Message-ID: <891bd3390906010434r145b38b9pe7d9ddbf223da3db@mail.gmail.com> Subject: Re: [Caml-list] Width subtyping From: Yaron Minsky To: Dario Teixeira Cc: caml-list@yquem.inria.fr Content-Type: multipart/alternative; boundary=00163630efc9459344046b47d061 X-Spam: no; 0.00; subtyping:01 yaron:01 minsky:01 yminsky:01 subtyping:01 sig:01 val:01 val:01 struct:01 compiler:01 compiler:01 subtypes:01 sig:01 struct:01 2009:98 --00163630efc9459344046b47d061 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit On Sun, May 31, 2009 at 7:08 PM, Dario Teixeira wrote: > > I also meant "heavier" in terms of efficiency. And like David said, it > does > feel wrong to carry the performance penalty of the object system solely > because > I need the structural subtyping features. If you're willing to give up some of the syntactic niceties of records (and the ability to pattern-match) you can get what you want using an abstract type. module type S = sig type 'a t val create_t1 : a : int -> b : int -> c : int -> [ `a | `b | `c ] t val create_t2 : a : int -> b : int -> c : int -> d : int -> [ `a | `b | `c | `d ] t val create_t3 : b : int -> c : int -> d : int -> [ `b | `c | `d ] t val a : [> `a ] t -> int val b : [> `b ] t -> int val c : [> `c ] t -> int val d : [> `d ] t -> int end module M : S = struct type u = { a: int; b: int; c :int; d: int } type 'a t = u let default = { a = 0; b = 0; c = 0; d = 0 } let create_t1 ~a ~b ~c = { default with a = a; b = b; c = c } let create_t2 ~a ~b ~c ~d = { a = a; b=b; c=c; d=d; } let create_t3 ~b ~c ~d = { default with b=b; c=c; d=d } let a t = t.a let b t = t.b let c t = t.c let d t = t.d end let f x = M.a x + M.b x let g () = f (M.create_t1 ~a:0 ~b:0 ~c:0) (* accepted by compiler *) let g () = f (M.create_t2 ~a:0 ~b:0 ~c:0 ~d:0) (* accepted by compiler *) let g () = f (M.create_t3 ~b:0 ~c:0 ~d:0) (* rejected by compiler *) The compiler error you get on that last line is this: Error: This expression has type [ `b | `c | `d ] M.t but is here used with type [> `a | `b ] M.t The first variant type does not allow tag(s) `a Here, we've chosen to use a default value for fields that we don't fill in. We could just as well have used options here. The performance of the above will be roughly the same as the performance of a simple record. Obviously, all of the different "subtypes" have the full record stored at a physical level. y --00163630efc9459344046b47d061 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: base64 T24gU3VuLCBNYXkgMzEsIDIwMDkgYXQgNzowOCBQTSwgRGFyaW8gVGVpeGVpcmEgPHNwYW4gZGly PSJsdHIiPiZsdDs8YSBocmVmPSJtYWlsdG86ZGFyaW90ZWl4ZWlyYUB5YWhvby5jb20iPmRhcmlv dGVpeGVpcmFAeWFob28uY29tPC9hPiZndDs8L3NwYW4+IHdyb3RlOjxicj48ZGl2IGNsYXNzPSJn bWFpbF9xdW90ZSI+PGJsb2NrcXVvdGUgY2xhc3M9ImdtYWlsX3F1b3RlIiBzdHlsZT0iYm9yZGVy LWxlZnQ6IDFweCBzb2xpZCByZ2IoMjA0LCAyMDQsIDIwNCk7IG1hcmdpbjogMHB0IDBwdCAwcHQg MC44ZXg7IHBhZGRpbmctbGVmdDogMWV4OyI+CjxkaXYgY2xhc3M9ImltIj48YnI+CjwvZGl2Pkkg YWxzbyBtZWFudCAmcXVvdDtoZWF2aWVyJnF1b3Q7IGluIHRlcm1zIG9mIGVmZmljaWVuY3kuIKBB bmQgbGlrZSBEYXZpZCBzYWlkLCBpdCBkb2VzPGJyPgpmZWVsIHdyb25nIHRvIGNhcnJ5IHRoZSBw ZXJmb3JtYW5jZSBwZW5hbHR5IG9mIHRoZSBvYmplY3Qgc3lzdGVtIHNvbGVseSBiZWNhdXNlPGJy PgpJIG5lZWQgdGhlIHN0cnVjdHVyYWwgc3VidHlwaW5nIGZlYXR1cmVzLiA8L2Jsb2NrcXVvdGU+ PGRpdj48YnI+SWYgeW91JiMzOTtyZSB3aWxsaW5nIHRvIGdpdmUgdXAgc29tZSBvZiB0aGUgc3lu dGFjdGljIG5pY2V0aWVzIG9mIHJlY29yZHMgKGFuZCB0aGUgYWJpbGl0eSB0byBwYXR0ZXJuLW1h dGNoKSB5b3UgY2FuIGdldCB3aGF0IHlvdSB3YW50IHVzaW5nIGFuIGFic3RyYWN0IHR5cGUuPGJy Pgo8YnI+PHNwYW4gc3R5bGU9ImZvbnQtZmFtaWx5OiBjb3VyaWVyIG5ldyxtb25vc3BhY2U7Ij5t b2R1bGUgdHlwZSBTID0gc2lnoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgIDwvc3Bhbj48YnIgc3R5bGU9ImZvbnQtZmFtaWx5OiBjb3Vy aWVyIG5ldyxtb25vc3BhY2U7Ij48c3BhbiBzdHlsZT0iZm9udC1mYW1pbHk6IGNvdXJpZXIgbmV3 LG1vbm9zcGFjZTsiPqCgIHR5cGUgJiMzOTthIHSgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgIDwvc3Bhbj48YnIgc3R5bGU9 ImZvbnQtZmFtaWx5OiBjb3VyaWVyIG5ldyxtb25vc3BhY2U7Ij4KPHNwYW4gc3R5bGU9ImZvbnQt ZmFtaWx5OiBjb3VyaWVyIG5ldyxtb25vc3BhY2U7Ij6goCB2YWwgY3JlYXRlX3QxIDogYSA6IGlu dCAtJmd0OyBiIDogaW50IC0mZ3Q7IGMgOiBpbnQgLSZndDsgWyBgYSB8IGBiIHwgYGMgXSB0oKCg oKCgoKCgIDwvc3Bhbj48YnIgc3R5bGU9ImZvbnQtZmFtaWx5OiBjb3VyaWVyIG5ldyxtb25vc3Bh Y2U7Ij48c3BhbiBzdHlsZT0iZm9udC1mYW1pbHk6IGNvdXJpZXIgbmV3LG1vbm9zcGFjZTsiPqCg IHZhbCBjcmVhdGVfdDIgOiBhIDogaW50IC0mZ3Q7IGIgOiBpbnQgLSZndDsgYyA6IGludCAtJmd0 OyBkIDogaW50oKCgoKCgoKCgoKCgoKCgoKCgoKAgPC9zcGFuPjxiciBzdHlsZT0iZm9udC1mYW1p bHk6IGNvdXJpZXIgbmV3LG1vbm9zcGFjZTsiPgo8c3BhbiBzdHlsZT0iZm9udC1mYW1pbHk6IGNv dXJpZXIgbmV3LG1vbm9zcGFjZTsiPqCgoKAgLSZndDsgWyBgYSB8IGBiIHwgYGMgfCBgZCBdIHSg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKAgPC9zcGFuPjxi ciBzdHlsZT0iZm9udC1mYW1pbHk6IGNvdXJpZXIgbmV3LG1vbm9zcGFjZTsiPjxzcGFuIHN0eWxl PSJmb250LWZhbWlseTogY291cmllciBuZXcsbW9ub3NwYWNlOyI+oKAgdmFsIGNyZWF0ZV90MyA6 IGIgOiBpbnQgLSZndDsgYyA6IGludCAtJmd0OyBkIDogaW50IC0mZ3Q7IFsgYGIgfCBgYyB8IGBk IF0gdKCgoKCgoKCgoCA8L3NwYW4+PGJyIHN0eWxlPSJmb250LWZhbWlseTogY291cmllciBuZXcs bW9ub3NwYWNlOyI+CjxzcGFuIHN0eWxlPSJmb250LWZhbWlseTogY291cmllciBuZXcsbW9ub3Nw YWNlOyI+oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoCA8L3NwYW4+PGJyIHN0eWxlPSJmb250LWZhbWls eTogY291cmllciBuZXcsbW9ub3NwYWNlOyI+PHNwYW4gc3R5bGU9ImZvbnQtZmFtaWx5OiBjb3Vy aWVyIG5ldyxtb25vc3BhY2U7Ij6goCB2YWwgYSA6IFsmZ3Q7IGBhIF0gdCAtJmd0OyBpbnSgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgIDwvc3Bhbj48 YnIgc3R5bGU9ImZvbnQtZmFtaWx5OiBjb3VyaWVyIG5ldyxtb25vc3BhY2U7Ij4KPHNwYW4gc3R5 bGU9ImZvbnQtZmFtaWx5OiBjb3VyaWVyIG5ldyxtb25vc3BhY2U7Ij6goCB2YWwgYiA6IFsmZ3Q7 IGBiIF0gdCAtJmd0OyBpbnSgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgIDwvc3Bhbj48YnIgc3R5bGU9ImZvbnQtZmFtaWx5OiBjb3VyaWVyIG5ldyxt b25vc3BhY2U7Ij48c3BhbiBzdHlsZT0iZm9udC1mYW1pbHk6IGNvdXJpZXIgbmV3LG1vbm9zcGFj ZTsiPqCgIHZhbCBjIDogWyZndDsgYGMgXSB0IC0mZ3Q7IGludKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKAgPC9zcGFuPjxiciBzdHlsZT0iZm9udC1m YW1pbHk6IGNvdXJpZXIgbmV3LG1vbm9zcGFjZTsiPgo8c3BhbiBzdHlsZT0iZm9udC1mYW1pbHk6 IGNvdXJpZXIgbmV3LG1vbm9zcGFjZTsiPqCgIHZhbCBkIDogWyZndDsgYGQgXSB0IC0mZ3Q7IGlu dKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKAgPC9z cGFuPjxiciBzdHlsZT0iZm9udC1mYW1pbHk6IGNvdXJpZXIgbmV3LG1vbm9zcGFjZTsiPjxzcGFu IHN0eWxlPSJmb250LWZhbWlseTogY291cmllciBuZXcsbW9ub3NwYWNlOyI+ZW5koKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoCA8L3NwYW4+PGJyIHN0eWxlPSJmb250LWZhbWlseTogY291cmllciBuZXcsbW9u b3NwYWNlOyI+CjxzcGFuIHN0eWxlPSJmb250LWZhbWlseTogY291cmllciBuZXcsbW9ub3NwYWNl OyI+oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoCA8L3NwYW4+PGJyIHN0eWxlPSJmb250LWZhbWlseTog Y291cmllciBuZXcsbW9ub3NwYWNlOyI+PHNwYW4gc3R5bGU9ImZvbnQtZmFtaWx5OiBjb3VyaWVy IG5ldyxtb25vc3BhY2U7Ij5tb2R1bGUgTSA6IFMgPSBzdHJ1Y3SgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgIDwvc3Bhbj48YnIgc3R5bGU9 ImZvbnQtZmFtaWx5OiBjb3VyaWVyIG5ldyxtb25vc3BhY2U7Ij4KPHNwYW4gc3R5bGU9ImZvbnQt ZmFtaWx5OiBjb3VyaWVyIG5ldyxtb25vc3BhY2U7Ij6gIHR5cGUgdSA9IHsgYTogaW50OyBiOiBp bnQ7IGMgOmludDsgZDogaW50IH2goKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgIDwv c3Bhbj48YnIgc3R5bGU9ImZvbnQtZmFtaWx5OiBjb3VyaWVyIG5ldyxtb25vc3BhY2U7Ij48c3Bh biBzdHlsZT0iZm9udC1mYW1pbHk6IGNvdXJpZXIgbmV3LG1vbm9zcGFjZTsiPqAgdHlwZSAmIzM5 O2EgdCA9IHWgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgIDwvc3Bhbj48YnIgc3R5bGU9ImZvbnQtZmFtaWx5OiBjb3VyaWVyIG5l dyxtb25vc3BhY2U7Ij4KPHNwYW4gc3R5bGU9ImZvbnQtZmFtaWx5OiBjb3VyaWVyIG5ldyxtb25v c3BhY2U7Ij6gIGxldCBkZWZhdWx0ID0geyBhID0gMDsgYiA9IDA7IGMgPSAwOyBkID0gMCB9oKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgIDwvc3Bhbj48YnIgc3R5bGU9ImZvbnQtZmFt aWx5OiBjb3VyaWVyIG5ldyxtb25vc3BhY2U7Ij48c3BhbiBzdHlsZT0iZm9udC1mYW1pbHk6IGNv dXJpZXIgbmV3LG1vbm9zcGFjZTsiPqAgbGV0IGNyZWF0ZV90MSB+YSB+YiB+YyA9IHsgZGVmYXVs dCB3aXRoIGEgPSBhOyBiID0gYjsgYyA9IGMgfaCgoKCgoKCgoKCgoKCgoKAgPC9zcGFuPjxiciBz dHlsZT0iZm9udC1mYW1pbHk6IGNvdXJpZXIgbmV3LG1vbm9zcGFjZTsiPgo8c3BhbiBzdHlsZT0i Zm9udC1mYW1pbHk6IGNvdXJpZXIgbmV3LG1vbm9zcGFjZTsiPqAgbGV0IGNyZWF0ZV90MiB+YSB+ YiB+YyB+ZCA9IHsgYSA9IGE7IGI9YjsgYz1jOyBkPWQ7IH2goKCgoKCgoKCgoKCgoKCgoKCgoKCg oKAgPC9zcGFuPjxiciBzdHlsZT0iZm9udC1mYW1pbHk6IGNvdXJpZXIgbmV3LG1vbm9zcGFjZTsi PjxzcGFuIHN0eWxlPSJmb250LWZhbWlseTogY291cmllciBuZXcsbW9ub3NwYWNlOyI+oCBsZXQg Y3JlYXRlX3QzIH5iIH5jIH5kID2gIHsgZGVmYXVsdCB3aXRoIGI9YjsgYz1jOyBkPWQgfaCgoKCg oKCgoKCgoKCgoKCgoKCgoCA8L3NwYW4+PGJyIHN0eWxlPSJmb250LWZhbWlseTogY291cmllciBu ZXcsbW9ub3NwYWNlOyI+CjxzcGFuIHN0eWxlPSJmb250LWZhbWlseTogY291cmllciBuZXcsbW9u b3NwYWNlOyI+oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoCA8L3NwYW4+PGJyIHN0eWxlPSJmb250LWZh bWlseTogY291cmllciBuZXcsbW9ub3NwYWNlOyI+PHNwYW4gc3R5bGU9ImZvbnQtZmFtaWx5OiBj b3VyaWVyIG5ldyxtb25vc3BhY2U7Ij6gIGxldCBhIHQgPSB0LmGgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgIDwvc3Bhbj48YnIg c3R5bGU9ImZvbnQtZmFtaWx5OiBjb3VyaWVyIG5ldyxtb25vc3BhY2U7Ij4KPHNwYW4gc3R5bGU9 ImZvbnQtZmFtaWx5OiBjb3VyaWVyIG5ldyxtb25vc3BhY2U7Ij6gIGxldCBiIHQgPSB0LmKgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgIDwvc3Bhbj48YnIgc3R5bGU9ImZvbnQtZmFtaWx5OiBjb3VyaWVyIG5ldyxtb25vc3BhY2U7 Ij48c3BhbiBzdHlsZT0iZm9udC1mYW1pbHk6IGNvdXJpZXIgbmV3LG1vbm9zcGFjZTsiPqAgbGV0 IGMgdCA9IHQuY6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKAgPC9zcGFuPjxiciBzdHlsZT0iZm9udC1mYW1pbHk6IGNvdXJpZXIg bmV3LG1vbm9zcGFjZTsiPgo8c3BhbiBzdHlsZT0iZm9udC1mYW1pbHk6IGNvdXJpZXIgbmV3LG1v bm9zcGFjZTsiPqAgbGV0IGQgdCA9IHQuZKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKAgPC9zcGFuPjxiciBzdHlsZT0iZm9udC1m YW1pbHk6IGNvdXJpZXIgbmV3LG1vbm9zcGFjZTsiPjxzcGFuIHN0eWxlPSJmb250LWZhbWlseTog Y291cmllciBuZXcsbW9ub3NwYWNlOyI+ZW5koKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoCA8L3NwYW4+PGJy IHN0eWxlPSJmb250LWZhbWlseTogY291cmllciBuZXcsbW9ub3NwYWNlOyI+CjxzcGFuIHN0eWxl PSJmb250LWZhbWlseTogY291cmllciBuZXcsbW9ub3NwYWNlOyI+oKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoCA8L3NwYW4+PGJyIHN0eWxlPSJmb250LWZhbWlseTogY291cmllciBuZXcsbW9ub3NwYWNl OyI+PHNwYW4gc3R5bGU9ImZvbnQtZmFtaWx5OiBjb3VyaWVyIG5ldyxtb25vc3BhY2U7Ij5sZXQg ZiB4ID0gTS5hIHggKyBNLmIgeKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgIDwvc3Bhbj48YnIgc3R5bGU9ImZvbnQtZmFtaWx5OiBjb3VyaWVy IG5ldyxtb25vc3BhY2U7Ij4KPHNwYW4gc3R5bGU9ImZvbnQtZmFtaWx5OiBjb3VyaWVyIG5ldyxt b25vc3BhY2U7Ij5sZXQgZyAoKSA9IGYgKE0uY3JlYXRlX3QxIH5hOjAgfmI6MCB+YzowKSAoKiBh Y2NlcHRlZCBieSBjb21waWxlciAqKaCgoKCgoKCgoKCgIDwvc3Bhbj48YnIgc3R5bGU9ImZvbnQt ZmFtaWx5OiBjb3VyaWVyIG5ldyxtb25vc3BhY2U7Ij48c3BhbiBzdHlsZT0iZm9udC1mYW1pbHk6 IGNvdXJpZXIgbmV3LG1vbm9zcGFjZTsiPmxldCBnICgpID0gZiAoTS5jcmVhdGVfdDIgfmE6MCB+ YjowIH5jOjAgfmQ6MCkgKCogYWNjZXB0ZWQgYnkgY29tcGlsZXIgKimgoKCgoKAgPC9zcGFuPjxi ciBzdHlsZT0iZm9udC1mYW1pbHk6IGNvdXJpZXIgbmV3LG1vbm9zcGFjZTsiPgo8c3BhbiBzdHls ZT0iZm9udC1mYW1pbHk6IGNvdXJpZXIgbmV3LG1vbm9zcGFjZTsiPmxldCBnICgpID0gZiAoTS5j cmVhdGVfdDMgfmI6MCB+YzowIH5kOjApICgqIHJlamVjdGVkIGJ5IGNvbXBpbGVyICopoKCgoCA8 L3NwYW4+PGJyPjwvZGl2PjwvZGl2Pjxicj5UaGUgY29tcGlsZXIgZXJyb3IgeW91IGdldCBvbiB0 aGF0IGxhc3QgbGluZSBpcyB0aGlzOjxicj48YnI+PHNwYW4gc3R5bGU9ImZvbnQtZmFtaWx5OiBj b3VyaWVyIG5ldyxtb25vc3BhY2U7Ij5FcnJvcjogVGhpcyBleHByZXNzaW9uIGhhcyB0eXBlIFsg YGIgfCBgYyB8IGBkIF0gTS50oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgIDwvc3Bhbj48YnIg c3R5bGU9ImZvbnQtZmFtaWx5OiBjb3VyaWVyIG5ldyxtb25vc3BhY2U7Ij4KPHNwYW4gc3R5bGU9 ImZvbnQtZmFtaWx5OiBjb3VyaWVyIG5ldyxtb25vc3BhY2U7Ij6goKCgoKAgYnV0IGlzIGhlcmUg dXNlZCB3aXRoIHR5cGUgWyZndDsgYGEgfCBgYiBdIE0udKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgIDwvc3Bhbj48YnIgc3R5bGU9ImZvbnQtZmFtaWx5OiBjb3VyaWVyIG5ldyxtb25vc3Bh Y2U7Ij48c3BhbiBzdHlsZT0iZm9udC1mYW1pbHk6IGNvdXJpZXIgbmV3LG1vbm9zcGFjZTsiPqCg oKCgoCBUaGUgZmlyc3QgdmFyaWFudCB0eXBlIGRvZXMgbm90IGFsbG93IHRhZyhzKSBgYaCgoKCg oKCgoKCgoKCgoKCgoDwvc3Bhbj6goKCgoKCgIDxicj4KPGJyPkhlcmUsIHdlJiMzOTt2ZSBjaG9z ZW4gdG8gdXNlIGEgZGVmYXVsdCB2YWx1ZSBmb3IgZmllbGRzIHRoYXQgd2UgZG9uJiMzOTt0IGZp bGwgaW4uoCBXZSBjb3VsZCBqdXN0IGFzIHdlbGwgaGF2ZSB1c2VkIG9wdGlvbnMgaGVyZS6gIFRo ZSBwZXJmb3JtYW5jZSBvZiB0aGUgYWJvdmUgd2lsbCBiZSByb3VnaGx5IHRoZSBzYW1lIGFzIHRo ZSBwZXJmb3JtYW5jZSBvZiBhIHNpbXBsZSByZWNvcmQuoCBPYnZpb3VzbHksIGFsbCBvZiB0aGUg ZGlmZmVyZW50ICZxdW90O3N1YnR5cGVzJnF1b3Q7IGhhdmUgdGhlIGZ1bGwgcmVjb3JkIHN0b3Jl ZCBhdCBhIHBoeXNpY2FsIGxldmVsLjxicj4KPGJyPnk8YnI+Cg== --00163630efc9459344046b47d061--