internal/filetypes: add options and mode defaults

- KeepDefautls, Incomplete

Change-Id: If4c2c63a01e3e2bb341c0a8577a46b0925708b6e
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/5091
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/internal/filetypes/filetypes.go b/internal/filetypes/filetypes.go
index 8345944..8e4269b 100644
--- a/internal/filetypes/filetypes.go
+++ b/internal/filetypes/filetypes.go
@@ -50,25 +50,24 @@
 // FileInfo defines the parsing plan for a file.
 type FileInfo struct {
 	*build.File
-	// Filename string `json:"filename"`
 
-	// Tags map[string]string `json:"tags"` // code=go
-
-	Definitions bool `json:"definitions"`
-	Data        bool `json:"data"`
-	Optional    bool `json:"optional"`
-	Constraints bool `json:"constraints"`
-	References  bool `json:"references"`
-	Cycles      bool `json:"cycles"`
-	Imports     bool `json:"imports"`
-	Stream      bool `json:"stream"`
-
-	Docs       bool `json:"docs"`
-	Attributes bool `json:"attributes"`
+	Definitions  bool `json:"definitions"`  // include/allow definition fields
+	Data         bool `json:"data"`         // include/allow regular fields
+	Optional     bool `json:"optional"`     // include/allow definition fields
+	Constraints  bool `json:"constraints"`  // include/allow constraints
+	References   bool `json:"references"`   // don't resolve/allow references
+	Cycles       bool `json:"cycles"`       // cycles are permitted
+	KeepDefaults bool `json:"keepDefaults"` // select/allow default values
+	Incomplete   bool `json:"incomplete"`   // permit incomplete values
+	Imports      bool `json:"imports"`      // don't expand/allow imports
+	Stream       bool `json:"stream"`       // permit streaming
+	Docs         bool `json:"docs"`         // show/allow docs
+	Attributes   bool `json:"attributes"`   // include/allow attributes
 }
 
 // FromFile return detailed file info for a given build file.
 // Encoding must be specified.
+// TODO: mode should probably not be necessary here.
 func FromFile(b *build.File, mode Mode) (*FileInfo, error) {
 	i := cuegenInstance.Value()
 	i = i.Unify(i.Lookup("modes", mode.String()))
@@ -121,7 +120,7 @@
 //     json: foo.data bar.data json+schema: bar.schema
 //
 func ParseArgs(args []string) (files []*build.File, err error) {
-	v := parseType("", Input)
+	inst, v := parseType("", Input)
 
 	qualifier := ""
 	hasFiles := false
@@ -130,7 +129,7 @@
 		a := strings.Split(s, ":")
 		switch {
 		case len(a) == 1 || len(a[0]) == 1: // filename
-			f, err := toFile(v, s)
+			f, err := toFile(inst, v, s)
 			if err != nil {
 				return nil, err
 			}
@@ -152,7 +151,7 @@
 			case qualifier != "" && !hasFiles:
 				return nil, errors.Newf(token.NoPos, "scoped qualifier %q without file", qualifier+":")
 			}
-			v = parseType(a[0], Input)
+			inst, v = parseType(a[0], Input)
 			qualifier = a[0]
 			hasFiles = false
 		}
@@ -183,14 +182,17 @@
 		return nil, errors.Newf(token.NoPos, "empty file name in %q", s)
 	}
 
-	return toFile(parseType(scope, mode), file)
+	inst, val := parseType(scope, mode)
+	return toFile(inst, val, file)
 }
 
-func toFile(v cue.Value, filename string) (*build.File, error) {
+func toFile(i, v cue.Value, filename string) (*build.File, error) {
 	v = v.Fill(filename, "filename")
-	if len(filename) > 1 { // omit "" and -
-		if s, _ := v.Lookup("encoding").String(); s == "" {
-			v = v.Unify(cuegenInstance.Lookup("extensions", filepath.Ext(filename)))
+	if s, _ := v.Lookup("encoding").String(); s == "" {
+		if len(filename) > 1 { // omit "" and -
+			v = v.Unify(i.Lookup("extensions", filepath.Ext(filename)))
+		} else {
+			v = v.Unify(i.LookupDef("Default"))
 		}
 	}
 	f := &build.File{}
@@ -200,9 +202,9 @@
 	return f, nil
 }
 
-func parseType(s string, mode Mode) cue.Value {
+func parseType(s string, mode Mode) (inst, val cue.Value) {
 	i := cuegenInstance.Value()
-	i = i.Unify(i.Lookup("modes", "def"))
+	i = i.Unify(i.Lookup("modes", mode.String()))
 	v := i.LookupDef("File")
 
 	if s != "" {
@@ -215,5 +217,5 @@
 		}
 	}
 
-	return v
+	return i, v
 }
diff --git a/internal/filetypes/filetypes_test.go b/internal/filetypes/filetypes_test.go
index d666ec6..4a38607 100644
--- a/internal/filetypes/filetypes_test.go
+++ b/internal/filetypes/filetypes_test.go
@@ -57,14 +57,16 @@
 				Encoding: "cue",
 				Form:     "schema",
 			},
-			Definitions: true,
-			Data:        true,
-			Optional:    true,
-			Constraints: true,
-			References:  true,
-			Cycles:      true,
-			Imports:     true,
-			Docs:        true,
+			Definitions:  true,
+			Data:         true,
+			Optional:     true,
+			Constraints:  true,
+			References:   true,
+			Cycles:       true,
+			KeepDefaults: true,
+			Incomplete:   true,
+			Imports:      true,
+			Docs:         true,
 		},
 	}, {
 		name: "yaml",
@@ -96,14 +98,16 @@
 				Interpretation: "openapi",
 				Form:           "schema",
 			},
-			Definitions: true,
-			Data:        true,
-			Optional:    true,
-			Constraints: true,
-			References:  true,
-			Cycles:      true,
-			Imports:     true,
-			Docs:        true,
+			Definitions:  true,
+			Data:         true,
+			Optional:     true,
+			Constraints:  true,
+			References:   true,
+			Cycles:       true,
+			KeepDefaults: true,
+			Incomplete:   true,
+			Imports:      true,
+			Docs:         true,
 		},
 	}, {
 		name: "JSONDefault",
@@ -131,14 +135,16 @@
 				Interpretation: "jsonschema",
 				Form:           "schema",
 			},
-			Definitions: true,
-			Data:        true,
-			Optional:    true,
-			Constraints: true,
-			References:  true,
-			Cycles:      true,
-			Imports:     true,
-			Docs:        true,
+			Definitions:  true,
+			Data:         true,
+			Optional:     true,
+			Constraints:  true,
+			References:   true,
+			Cycles:       true,
+			KeepDefaults: true,
+			Incomplete:   true,
+			Imports:      true,
+			Docs:         true,
 		},
 	}, {
 		name: "JSONOpenAPI",
@@ -154,14 +160,16 @@
 				Interpretation: "openapi",
 				Form:           "schema",
 			},
-			Definitions: true,
-			Data:        true,
-			Optional:    true,
-			Constraints: true,
-			References:  true,
-			Cycles:      true,
-			Imports:     true,
-			Docs:        true,
+			Definitions:  true,
+			Data:         true,
+			Optional:     true,
+			Constraints:  true,
+			References:   true,
+			Cycles:       true,
+			KeepDefaults: true,
+			Incomplete:   true,
+			Imports:      true,
+			Docs:         true,
 		},
 	}, {
 		name: "OpenAPIDefaults",
@@ -173,18 +181,20 @@
 		out: &FileInfo{
 			File: &build.File{
 				Filename:       "-",
-				Encoding:       "yaml", // Input default
+				Encoding:       "json",
 				Interpretation: "openapi",
 				Form:           "schema",
 			},
-			Definitions: true,
-			Data:        true,
-			Optional:    true,
-			Constraints: true,
-			References:  true,
-			Cycles:      true,
-			Imports:     true,
-			Docs:        true,
+			Definitions:  true,
+			Data:         true,
+			Optional:     true,
+			Constraints:  true,
+			References:   true,
+			Cycles:       true,
+			KeepDefaults: true,
+			Incomplete:   true,
+			Imports:      true,
+			Docs:         true,
 		},
 	}, {
 		name: "Go",
@@ -199,15 +209,17 @@
 				Form:     "schema",
 				Tags:     map[string]string{"lang": "go"},
 			},
-			Definitions: true,
-			Data:        true,
-			Optional:    true,
-			Constraints: true,
-			References:  true,
-			Cycles:      true,
-			Imports:     true,
-			Stream:      false,
-			Docs:        true,
+			Definitions:  true,
+			Data:         true,
+			Optional:     true,
+			Constraints:  true,
+			References:   true,
+			Cycles:       true,
+			KeepDefaults: true,
+			Incomplete:   true,
+			Imports:      true,
+			Stream:       false,
+			Docs:         true,
 		},
 	}}
 	for _, tc := range testCases {
@@ -238,6 +250,13 @@
 			Form:           "schema",
 		},
 	}, {
+		in: "openapi:-",
+		out: &build.File{
+			Filename:       "-",
+			Encoding:       "json",
+			Interpretation: "openapi",
+		},
+	}, {
 		in: "cue:file.json",
 		out: &build.File{
 			Filename: "file.json",
diff --git a/internal/filetypes/types.cue b/internal/filetypes/types.cue
index 0ea0aa4..8a26ca9 100644
--- a/internal/filetypes/types.cue
+++ b/internal/filetypes/types.cue
@@ -31,24 +31,31 @@
 	tags?: {[string]: string}
 }
 
+// Default is the file used for stdin and stdout. The settings depend
+// on the file mode.
+Default :: File & {
+	filename: *"-" | string
+}
+
 // A FileInfo defines how a file is encoded and interpreted.
 FileInfo :: {
 	File
 
-	// Settings
-	data:       *true | false
-	references: *true | false
-	cycles:     *true | false
+	// For each of these fields it is explained what a true value means
+	// for encoding/decoding.
 
-	definitions:  bool
-	optional:     bool
-	constraints:  bool
-	keepDefaults: bool
-	incomplete:   bool
-	imports:      bool
-	stream:       bool
-	docs:         bool
-	attributes:   true | *false
+	data:         *true | false // include/allow regular fields
+	references:   *true | false // don't resolve/allow references
+	cycles:       *true | false // cycles are permitted
+	definitions:  bool          // include/allow definition fields
+	optional:     bool          // include/allow definition fields
+	constraints:  bool          // include/allow constraints
+	keepDefaults: bool          // select/allow default values
+	incomplete:   bool          // permit incomplete values
+	imports:      bool          // don't expand/allow imports
+	stream:       bool          // permit streaming
+	docs:         bool          // show/allow docs
+	attributes:   true | *false // include/allow attributes
 }
 
 // modes sets defaults for different operational modes.
@@ -61,6 +68,11 @@
 // In input mode, settings flags are interpreted as what is allowed to occur
 // in the input. The default settings, therefore, tend to be permissive.
 modes: input: {
+	Default :: {
+		encoding: *"cue" | _
+		...
+	}
+
 	FileInfo :: x, x = {
 		docs: *true | false
 	}
@@ -70,6 +82,20 @@
 }
 
 modes: export: {
+	Default :: {
+		encoding: *"json" | _
+		...
+	}
+
+	FileInfo :: x, x = {
+		docs: true | *false
+	}
+	encodings: cue: {
+		*forms.data | _
+	}
+}
+
+modes: ouptut: {
 	FileInfo :: x, x = {
 		docs: true | *false
 	}
@@ -79,6 +105,11 @@
 }
 
 modes: def: {
+	Default :: {
+		encoding: *"cue" | _
+		...
+	}
+
 	FileInfo :: x, x = {
 		docs: *true | false
 	}
@@ -160,8 +191,14 @@
 		tags: lang: string
 	}
 
-	jsonschema: interpretation: "jsonschema"
-	openapi: interpretation:    "openapi"
+	jsonschema: {
+		interpretation: "jsonschema"
+		encoding:       *"json" | _
+	}
+	openapi: {
+		interpretation: "openapi"
+		encoding:       *"json" | _
+	}
 }
 
 // forms defines schema for all forms. It does not include the form ID.
@@ -278,10 +315,10 @@
 
 interpretations: jsonschema: {
 	forms.schema
-	encoding: *"yaml" | _
+	encoding: *"json" | _
 }
 
 interpretations: openapi: {
 	forms.schema
-	encoding: *"yaml" | _
+	encoding: *"json" | _
 }
diff --git a/internal/filetypes/types.go b/internal/filetypes/types.go
index 99f43a2..6fd1edd 100644
--- a/internal/filetypes/types.go
+++ b/internal/filetypes/types.go
@@ -47,5 +47,5 @@
 	return v
 }
 
-// Data size: 1051 bytes.
-var cuegenInstanceData = []byte("\x01\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xbcWKo\u0736\x13\x17\xd7\xfe\x03\u007f\x12q\xbfA\x01U\x87\xc2\xd9\xc3^\v,\x10\xf8\x92\x06\u0225(z5\x02\x83\x96(Y\x8d\x96\x14$.`#\xbb\x87\xb6i\xdaK\xbfr\xb6\x18\x0e\x1f\"\xa55\x9a\x1e\xca\xd3\xea7\x9c7\xe7\xb1W\xa7?Vdu\xfa3#\xa7_\xb3\xec\xbb\xd3/\x17\x84\xbch\u5a39,\xc5k\xae9\xe0\xe4\x82\\\xfe\xa4\x94&\xab\x8c\\\xfe\xc8\xf5\x03y\x91\x91\xff\xbdi;1\x92\u04e7,\u02fe>\xfd\xbe\"\xe4\xab\xdbw\xe5^l\uadb3\x9c\x9f2r\xfa\x98e\u05e7\xdf.\b\xf9\u007f\xc0?fdE.\u007f\xe0;\x01\x82.\r\u0232,\xfb|\xf5\x17XB\u020a\x10\xaa\x9fz1n\u02bd \x9f\xaft\xcf\xcb\xf7\xbc\x11\xf9\xfd\xbe\xed*\xc6@u\xbe\xdd\xe6\x1f\x18\x05\xa9\x92\xef\xc46\xb7g\xd4C+\x1bF\x85,U\xd5\xca\xc6\x13\xbe\xb7\x00\xa3\xad\xd4b\xe8\a\xa1\xb9n\x95\xbc\xd9\xe6o#\x80\xd1Z\r\xbb\x1b\u03d8\xe7\xf9\x1b5\xec\x18\u057c\x19o\x8cVz\x8bj\xdem\xbd\xbe#;2\xa7\x02l\xc3\xf3\u036b\xa2`\xb1x Z&\x10\x1b\xeeN\xac\aMF\x91\x16\x8f\x1a5\x06\u007f\n\x00\vF\x8d\x99\xc8\\T\\\xf3\x02\x8c\xa0\xf0\v9\x90<!\x95{1\x93U\xee\x05\x12\xc7\xf2A\xecbN\x84\x90\xfc\xf3\xa8\xe4\x8c\x19@ \xe7\xdf\xe6\xd7\xeb\xc0\xb8.\x8a\xfc\x10\x14\xe7\a\xc3\x17G\x1dn\x01\xbb\u0551\x1f\xf2\xbb\xc8#<\xeb\"\u040b\xba\x95\xbc\x03\x81/\u045cn\u045e\x0e\xed}\xe2\xbb9\x1d@$7*%\xe2)JUA@f\xd6\x16\x00\xfa\xb4P\xdaq#\xb1Q\x80\x1f\x8d\xcc~Pz&\xb60(*5\x0eD\x11\xf6.1\xda\f\xbc\u007f\x88\x88\x06qIm\x92\x9c66\xa5\xaa\x9a\xe5\xf4_y\u27b1\xf5%\xa4f\xbb\x98\xbci\xee\f\x83\xea\x85\xe4}{\u6da5\x16X&P\xbeoe\xadl\t\xe3\x8b\xf5)\xd7\xc3^\u41fc\xe6\xdd(\x18\x1dD-\x06!K1n\xe7\xc4\xf2\xa9\uc430\xc0Y\x89\xba\x95-\x18\x007\xee\x95\xea\xc0J\xf8\x86$\xc0A\xacTr\xd4\x03o\xa5\x0e\xf7\xde\v\u047f\x165\xdfw\x00\"\xd6\xcaR\xed\xfaNh\xd3k,\xb6\xeb\u0560\x9d\x05\x88\x8dz\x10\u073fb\xc4*U\x8e\xc1E\u0138\xd6C{\xbf\xd7\u8035}m\x8d\x87\x10\xb1#\u06e9J`\x9eZ\xd9\xefm'H\xc2G\xad\xf4\xc4}J7\x9b\r\xe6\u04ff\r\x97r\xdf\b(]\u00cb\x1a7\x98J[\x85\x86\u01fc\x03\xa8\xec\x0f\x8c\x8aGp\xf3Y\xed\x89\xfd_\xa6\x1d^\xc09\u0755\xa8\xff{\xb7Y\xcc\xea\x19]n\xad2od\xe8\x8e\xee\x06\x06\"?\x98\xc00\xea_\x80338>\x11\x13\x9aV\xa4\b\xe2j\xc5 \x9b\xe9\f\x89\xfa\x841\xba\x9f\xa8\tC%\xf1\xe7\xccu\xb5h\u0579\xeb\u03f7A:\r\xfc\x84+4\xb2e%\x13\x06f\x10s\xf9\x16\x96\x88W~\x16\xbb'\xe2\x84\x16\xc56\xbfs\x1f\xf3\x01\xf7\u0314\x81_\xae\xff&\x9d$}pqO\xb9\x8e\xc8/\xcdd\x8c\x10F\x93\x8e\x93\u028b{OJ\x8d\xbb\u040c\x1a\xf5\xa3\x94\x1aw\xa6\xa4b}&fS\xca\x1d?\xad\x12\x97\x97\r?\x9b>\xd42\x1bw!\x19\x18w\xdc \x9a\xe9&\x91L\nWYQv\x96\xb3\xe2\xd08\xf2\xcf\x1b\x1eGz9\xc2i\xec\x929m\xf6?\xff\x8c\u0734\x8a#\x93\xd6r\xba\xbf\x85E\x12\x87~<\x11\xbdc\xd3I\xb8\x18\x83\xc5\x10,z\x95V\xb7]n\u0163\x16r\xc40\xdb\u06b2\xe7\x8e\xd1\x026uD`\xb5\x80/\x00\u0342\xb8u |9\xb4\x03\u0623\x1d\xc0]e\xaf\u01f0\\\x86\xcd.\xe7E\u00d7A-\x18\xa3\xfaQOPh\u007f\x806\u02ba`\xd0F\x01\x86m\u0299f\xbe\xa0\u1d1d\b\xdd\u0155\x89\xfb\xe3Q\xd4Jm\xec*<Y\xc9\xddvtd\xf1:\xf4\xe5\x9d+]\xc6B[]\xe3J;\u065e\x17J-Z\xcd\xfe1/\u02f2\xbf\x03\x00\x00\xff\xff\xea*w\xba\x1d\x0e\x00\x00")
+// Data size: 1097 bytes.
+var cuegenInstanceData = []byte("\x01\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xd4WO\x8b\xdc6\x14\xb7f\xb7P\xa9i\xfa\t\n\xae\x0ea3\u0439\x16\x06\xc2^\xd2@.\xa5\xf4\xba\x84Ek\xcb^7\x1e\xc9\xd82\xec\u0499C\xdb4\xed\xe7\xed\a\u0214\xa7'\u0656\xec\xd9%9\x14\xa2\x93\xf5{z\xff\x9f\x9e\x9e\xbf>\xfe\xbd\"\xab\xe3?\t9\xfe\x91$?\x1c\u007f?#\xe4I\xa5:#T&_\n#\x00'g\xe4\xfc\x17\xad\rY%\xe4\xfcgan\u0253\x84|\xf1\xaa\xaaeG\x8e\xef\x93$\xf9\xf6\xf8\u05ca\x90\xa7Wo\xb2^n\x8a\xaav\x9c\xef\x13r|\x97$\x17\xc7?\xcf\b\xf9r\xc4\xdf%dE\xce\u007f\x12;\t\x82\xce-\u0212$\xf9\xf0\xcdW`\t!+B\xa8\xb9od\xb7\xc9zI><\xfd\xb7\x11\xd9[Q\xca\xf4\xa6\xaf\xea\x9c1P\x9dn\xb7\xe9o\x8c\x82T%vr\x9b\xba\u0559\xb6R%\xa3Re:\xafT9\x10~t\x00\xa3\x952\xb2mZi\x84\xa9\xb4\xba\u0726\xaf\x03\x80\xd1B\xb7\xbb\u02c11M\xd3W\xba\xdd1jD\xd9]Z\xad\xf4\n\u057c\xd9\x0e\xfa\x0e\xec\xc0\xbc\n\xb0\r\xd7w/8g\xa1x :&\x10;\x9e\x9dX\x0f\x9a\xac\"#\xef\fj\x1c\xfd\xe1\x00rF\xad\x99\xc8\xccsa\x04\a#(|!\a\x92'\xa4\xac\x973YY/\x91\xd8e\xb7r\x17r\"\x84\xe4_;\xadf\xcc\x00\x029}\x96^\xacG\xc65\xe7\xe9~T\x9c\xee-_\x18u8\x05\xecNG\xbaO\xaf\x03\x8fp\xad\xf9H\xe7E\xa5D\r\x02\x9f\xa39\xf5\xa2=5\xda{/vs:\x80H.uL\xc4\xc53\x9dC@f\xd6r\x00\x87\xb4PZ\v+\xb1\u0500\x1f\xac\u0326\xd5f&\x96[\x14\x95Z\a\x82\b\x0f.1Z\xb6\xa2\xb9\r\x88\x16\xf1I-\xa3\x9c\x96.\xa5:\x9f\xe5\xf4\x93<\xf1e\xec|\x19S\xb3,\x1d\x93\xe7\xd36S1\u026c\x15\xa7\x1b\xa9DS}\x92,\xc7\xcb\U0004af54\x85\xe8k\x03\xb7\xc6v\x81ga\x13X\xf3\xefA\x90\xf3\xe6`;\xc5kUh\xd7-\xf0r\f\xd5e\xda^\xa6\xfb\xb4\x10u'\x19me![\xa92\xd9m\xe7\xc4\xec>\xab\x91\xb0\xc0\x99\u02e2R\x15\xd8\v'n\xb4\xae\xc1e\xd8C\xbea!\x96i\u0559VT\u028c\xe7\xdeJ\xd98\xa7\xba\xad\xc3*\x95\xe9]SKc\u06da\xc3v\x8dn\x8d\xb7\x00\xb1\u03b4R\f\x17\x06\xb1\\g\xdd\xe8\"b\u0098\xb6\xba\xe9\r:\xe0l_;\xe3!D\xec\xc0v:\x97X\x12\x95jz\xd7t&\u0476\xb52\xa6nm;\x87\xcb\x19\xddl6X:4\n8u\xf6D\x01\x9brx\x99\xbe\x1e\x87.E\xe9\x1a\u02bd\xdb`%y]\a_\xa4\aL\xbe\xbc\x83\xc0<n\xef\xb4\xc8\x1e78\n\xd2\xc7\x19\fev\xca\\\xdd7\u0187\xf7\xff\u059d\xcb\xe2s\xc8+\vY\aF_\xeeN\xd9\xe0\xd6\xf86\xf9\x13\x18\xbatoC\xc9\xe8p)\xbc\x99c\xa8&b\xc6'#P\x04\x99pb\x90\xcd\xf6\xe5H}\xc4\x18\x9c\x8f\u050cOz\xe4\u03c9\xe3z\u046aS\xc7\x1f~\x84\xe84\xf0\x13\xae\xf1\x19YV2a`\x16\xb1\x87\xaf`\x84{1LB\xbeD\xbcP\u03b7\xe9\xb5\xdf\xcc\u01cb\a\xdex\xf8\xf2\xaf_\xd4\\\xe3\x82\v\xdb\xecE@~n\xe7\x92\x00a4j\u00b1\xbc\xb0\x1d\xc7\u05301\u03e8A\x8b\x8e\xa9a\xb3\x8e\xee\xf8\x90\x89\u064c\xe0\xd70+D./\x1b~2}\xa8e6l\x8c\xc9\xc0\xb8\xe3\xfcVN\xe7\xb8\xe8\xf1\xf47+\xc8\xcerV<\x1aF\xfea\xc3\xc3H/G8\x8e]4%\xd9\xe9{(#\xff\x80\x87\x91\x89\xefr<=\x8fc<\x8e\\\xe1\x90086\x1d\x0e\x16c\xb0\x18\x82E\xaf\xe2\xdb\xed~-\u4751\xaa\xc30\xbb\xbb\xe5\xd65\xa3\x1c\xfe\x93\x10\x81\xc1\x0ev\x00\xda\x17o\xebA\xd8y\xb4\x06x@k\x80\xeb\xdc\x1d\x0fa\xb5\f\xdbIz\x10\r;\x8b:0D\u035d\x99\xa0\xd0\xfe\x00-\xb5s\xc1\xa2\xa5\x06\f\u06d47\xcd\xee\xa0\xe1T\xb5\x1c\xbbK<\xf1\xf1B\xeb\x8d\xfb\x11\x99\xfc\x10\xf9\xe9\xf3\xc0\u0081\xf2\xe3;\xd7\xe9Q8\x9c)N\\\xb5\x13\xa3\xef#\xbc,I\xfe\v\x00\x00\xff\xff\xf1\xf9\xbd5\x9b\x0f\x00\x00")