1(**
2# First-level heading
3Some more documentation using `Markdown`.
4*)
5module SampleCode.SimpleTypes
6
7(**
8This comments was making the whole file render as a comment.
9**)
10
11// Compiler directives
12
13#if true
14#elif false
15#elseif false
16#endif
17#light "on"
18#nowarn
19#nowarn "9" "40"
20
21open System.Text// check that comments are handled correctly
22open System.Text // check that comments are handled correctly
23open System.Text.RegularExpressions(* check that comments are handled correctly *)
24open System.Text.RegularExpressions (* check that comments are handled correctly *)
25
26module Test =
27
28 (** **Check** that this line isn't capture for the markdown grammar **)
29 let a = ""
30
31 (**
32 This is an edge case, because in early implementation this is commented the whilte file
33
34 Line with indentation isn't colorized because markdown can't set up his context.
35 *)
36 let b = ""
37
38 (**
39This block is colorized becasue markdown can set up his context.
40
41# First-level heading
42This should be parsed as `markdown`.
43This is an edge case, because in early implementation this is parser the whole
44file as markdown
45 *)
46 let c = ""
47
48 (* Comments with nested (* (* *) *) works
49
50 This line should be shown commented.
51 class should not be colored
52 *)
53 let d = ""
54
55 let e = (* comment// *) "not a comment"
56
57/// **Description**
58///
59/// **Parameters**
60/// * `arg1` - parameter of type `string`
61/// * `arg2` - parameter of type `string`
62///
63/// **Output Type**
64/// * `string`
65///
66/// **Exceptions**
67///
68let markdownDemo (arg1 : string) (arg2 : string) =
69 ""
70
71/// **Checking that markdown is really working on single line**
72let markdownDemo2 (arg1 : string) (arg2 : string) =
73 ""
74
75// **This comment isn't formatted**
76
77(* Neither this one *)
78
79exception UndefinedValueException of string
80
81type Alias = int
82
83type Alpha = class end
84
85type LightDU =
86 | CaseA
87 | CaseB
88
89type EgalNewLine
90 = CaseA
91 | CaseB
92
93type Underscore_Name = | Underscore_Name of string
94
95let i32 = typeof<int>
96let list = typedefof<_ list>
97
98type Accentué = int
99
100type Class1() =
101 member this.X = "F#"
102
103// Check accessibility modifier coloring
104type R = private { X : int }
105type U = private | X of int
106
107let private getArgResults, private removeArgResults, private setArgResults = "", "", ""
108
109// Check builder detection (based on a whitelist)
110let a = promise { }
111let b = pipeline { }
112let c = noColor { }
113
114// Check that known builder names aren't captured as builders when a
115// value name begins with one of them (e.g. `asyncResult`)
116// Also see ionide/ionide-vscode-fsharp#836
117let d =
118 let asyncF = async { }
119 asyncF
120
121// Whitespace between builder and opening brace is optional
122let e = async{ return 0 }
123
124type FancyClass(thing:int, var2 : string -> string, ``ddzdz``: string list, extra) as xxx =
125
126 let pf() = xxx.Test()
127 let mutable myInternalValue = null
128
129 member xxx.Test() = "F#"
130
131 // A read-only property.
132 member __.MyReadOnlyProperty = myInternalValue
133 // A write-only property.
134 member __.MyWriteOnlyProperty with set (value) = myInternalValue <- value
135 // A read-write property.
136 member __.MyReadWriteProperty
137 with get () = myInternalValue
138 and set (value) = myInternalValue <- value
139
140 member __.ReadAndWriteWithSignature
141 with get (count : int) : string = string count
142 and set (value : int) : unit = failwith ""
143
144 member __.MyReadWriteProperty with get () = myInternalValue
145 member __.MyReadWriteProperty with set (value) = myInternalValue <- value
146
147 abstract Update : int * string * string option * obj -> FancyClass
148 default this.Update (thing:int, var2 : string, ``name withh spaces``: string option, extra) = this
149
150 member val Property1 = thing
151 member val Property2 = "" with get, set
152
153 /// The typo in withh is intentional, because with is one of the `end` possibility
154 /// We consider it ok, because there is a low chance that a person will use `with` in a quoted variable
155 member __.Test2(thing:int, var2 : string, ``name withh spaces``: string option, extra) = ""
156
157 static member (>) (v1 : int, v2 : int) = v1 > v2
158 static member (<) (v1 : int, v2 : int) = v2 < v2
159 static member (< ) (v1 : int, v2 : int) = v2 < v2
160 static member (<|>) (v1 : int, v2 : int) = v2 < v2
161
162let inline internal (<) (x : int) ys = x + ys
163let (< ) (x : int) ys = x + ys
164let (<<.) a = 1
165let inline internal (<==) (x : int) ys = x + ys
166let inline internal (<==) x ys = x + ys
167
168// Check that this `get` and `set` methods are not messing the colourisation
169let get = ignore
170get ("maxime")
171let set = ignore
172set("maxime")
173
174// Arrow should be colored as a keyword and int as type definition
175let exec (buildOptions: int -> int -> int -> int) args = ""
176
177// This line is to check that member_declaration isn't propagate output of declaration scopes
178let p value = System.Int32.Parse(value)
179
180type TestGeneric<'arg, 'model, 'msg, 'view> private (*comments test*) (a: 'arg, model: 'model, msg: 'msg, view: 'view, notify : string -> unit ) as xxx =
181 class end
182
183type ``Program with spaces``<'arg, 'model, 'msg, 'view> =
184 class end
185
186type Program<'arg, 'model, 'msg, 'view> =
187 { Arg : 'arg
188 Model : 'model
189 Msg : 'msg
190 View : 'view }
191
192
193type Decoder<'a> =
194 class end
195
196let keyValuePairs (decoder : Decoder<'value>) : Decoder<(string * 'value) list> = failwith ""
197let keyValuePairs (decoder : Decoder<'value>) : Decoder<(string * 'value) list -> obj> = failwith ""
198let tuple2 (decoder1: Decoder<'T1>) (decoder2: Decoder<'T2>) : Decoder<'T1 * 'T2> = failwith ""
199
200let run (program : Program<'arg, 'model, 'msg, 'view>) = ""
201let run2 (program : unit -> Program<'arg, 'model, 'msg, 'view>) = ""
202
203type T =
204 abstract Item: selector: string -> string with get, set
205 abstract icon: width : int * height : int with get, set
206 abstract member Name: string option with get, set
207 abstract member NameTestComment: string (*I am a comments*) option with get, set
208 abstract member NameTestComment2: string //option with get, set
209 abstract member Keys: unit -> Program<'arg, 'model, 'msg, array<array<array<'view>>>>
210 abstract Run : program : Program<'arg, 'model, 'msg, array<array<array<'view>>>> -> unit
211 abstract ``open``: cacheName: string -> obj
212 abstract DrawElementsInstancedANGLE: mode: float * count: float * ``type with spaces``: float * offset: float * primcount: float
213 abstract Test : Result<string list, int array>
214 abstract Test2 : mode: float * test : (Result<Result<Result<Result<string, string>, string>, string> list, int array> * int)
215 abstract TupleOfTuples : (int * (int * (Result<Result<Result<Result<string, string>, string>, string> list, int array> * int)))
216
217type FancyClass with
218 member __.Run (program : Program<'arg, 'model, 'msg, array<'view>>) = ()
219
220type FancyClass1(?thing:int) =
221 class end
222
223type private FancyClass2 (?thing:int) =
224 class end
225
226type FancyClass3 private (?thing:int) =
227 class end
228
229let foo =
230 { new System.IDisposable with
231 member __.Dispose() =
232 failwith "do nothing" }
233let bar =
234 use foo = new System.Threading.CancellationTokenSource()
235 ()
236
237let paramsColorWorksHereToo (client : obj, extraParam) (name : unit -> obj) : string = ""
238
239let endOfThisLineShouldBeCommented// (client : obj, extraParam) = ""
240 : string = ""
241
242// Fixed width comments also works and coloration is still correct after it
243let endOfThisLineShouldBeCommented2 (*(client : obj, extraParam) = ""*) (name: int) = ""
244
245// Fixed width comments also works even in tuples parameters
246// and coloration is still correct after it
247let private _emitLetBinding (il:int, (*methods:MethodSymbolTable, locals:LocalsSymbolTable,*) binding:obj) =
248 ""
249
250type EndOfThisLineShouldBe //Commented (a:int, b:int)
251 (a: int, b: int) =
252 class end
253
254let (name : string, age) = "", 0
255
256type NameRecord =
257 { Firstname : string
258 Surname : string }
259
260type NestedRecord =
261 { Nested : NestedRecord
262 PropB : string }
263
264
265// Test signature coloration
266let primitive : int = 0
267
268let tupleOfPrimitives : int * string list = 0, []
269let tupleOfPrimitives : (int * string) = 0, ""
270let tupleOfTuples : (int * (int * (int * int))) = failwith ""
271let tupleOfTuples : int * (int * (Result<Result<Result<Result<string, string>, string>, string> list, int array> * int)) = failwith ""
272let tupleOfTuples : (int * (int * (Result<Result<Result<Result<string, string>, string>, string> list, int array> * int))) = failwith ""
273let listOfTuples
274 (files : (string * string) list)
275 (files2 : (string * string) list)
276 : (int * (int * (Result<Result<string, string> list, int array> * int))) list = []
277let generics : Result<string list, int array> = Ok []
278
279let tupleWithGenerics : Result<string list, int array> * int = Ok [], 0
280let tupleWithAListOfGenerics (p1 : int * Map<int, int> list) (p2 : int * Map<int, int> list) : int * Map<int, int> list = 1, []
281let tupleWithAListOfGenerics : int * Map<int, int> list = 1, []
282let tupleWithAListOrArrayOfGenerics2 : int * Map<int, int> list * Map<int, int> array = 1, [], [||]
283
284// Really complexe nested generic type
285let tupleWithGenerics2 : (Result<Result<Result<Result<string, string>, string>, string> list, int array> * int) = Ok [], 0
286
287let lambda : int -> unit = ignore
288let lambda : (int -> unit) = ignore
289let lambda : (int -> unit) -> unit = ignore
290let lambda : (Result<string list, int array> -> (string * int)) -> unit = ignore
291let lambda : (Result<Result<Result<Result<string, string>, string>, string> list, int array> -> Result<Result<string, string> list, int array> * int) -> unit = ignore
292let lambda ( x : (Result<Result<Result<Result<string, string>, string>, string> list, int array>
293 -> Result<Result<Result<Result<string, string>, string>, string> list, int array> * int)
294 -> unit) : ('T -> unit ) = ignore
295
296let inline isLoadingTime<'a> = ""
297let inline isLoadingTime<'a, 'b, 'c> = ""
298let inline method<'a> prefix chunck dzd zd = promise {
299 let! dzdz = ""
300 }
301
302
303let v ``var with spaces``= ""
304
305let printFullName { Firstname = firstname; Surname = surname } : string = firstname + " " + surname
306let printFirstName { Firstname = firstname } : string = firstname
307let printFirstName ({ Firstname = ``var with spaces`` } : NameRecord) ( _ : obj) : string = ``var with spaces``
308
309
310let ``test multiple backticks`` = row.``maxime``.Trim(), row.``Last Update`` // Test multiple backticks on the same line
311
312let nestedRecords ({ Nested = { Nested = { Nested = { Nested = value }; PropB = _ } }; PropB = propB } : NestedRecord) : string = value.PropB + " " + propB
313
314let variable = "value"
315
316// Check that style is apply even when declaration is on multiple lines
317let func arg1 arg2 = ""
318
319let func
320 arg1 arg2 = ""
321
322let func
323 arg1
324 arg2 = ""
325
326// Check that option is also colored as part of the type definition
327let debounce (debounce : int option) = ""
328
329// Check output type coloration
330let mutable timeoutID : float = 0.
331let test2 test (timeoutID : float option) : int option = None
332
333module test =
334 let t = 1
335
336module accentué =
337 let t = 1
338
339open test
340
341type MutableMembersTest = {
342 mutable test: string
343}
344
345// Test that variable named like: keyword' isn't colored in a match statement
346let test match' =
347 match match' with
348 | CaseA -> ""
349 | CaseB -> ""
350
351let test2 return' =
352 match return' with
353 | CaseA -> ""
354 | CaseB -> ""
355
356type RequestData =
357 { Params : string }
358
359type Client () =
360 member this.Request (req : RequestData) = ""
361
362let res (client : Client, extraParam) = client.Request { Params = "" }
363
364[<Measure>]
365type kg
366
367let forLoop =
368 [ for index = 0 to 1 do
369 yield index ]
370
371type GenType<'a> = 'a
372
373type ``type with spaces`` = obj
374
375let t : ``type with spaces`` = null
376let t2 : obj = null
377
378type TestDUTypeColoration =
379 | CaseA
380 | CaseB of int
381 | CaseC of (int * (string * string) list)
382 | CaseD of name :string * age:int
383 | CaseE of client: Client
384 | CaseF of client: Client (*comment tests*) * (*comment tests*) string * port : int
385 | CaseG of (obj -> unit)
386 | CaseH of string * (obj -> unit)
387 // Check multiple declaration on one line
388 | CaseI of int | CaseJ of int
389 | CaseF2 of client: Client // * string * port : int
390 | FetchDomainsSuccess of Result<int list * ``type with spaces`` * int, ``type with spaces``>
391 | CaseK of ``var with spaces``: string
392 | CaseL of ``var with spaces``: ``type with spaces``
393 | CaseM of v1 : ``type with spaces``
394 | CaseN of ``type with spaces``
395
396type TestRecordColoration<'a> =
397 { Firstname : string
398 Lastname : string
399 /// Test docs comments works with `markdown`
400 Age : (*comment tests*) int
401 Notify : string -> unit
402 Notify2 : string ->unit
403 Notify3 : string-> unit
404 Notify4 : string -> unit
405 Callback : (string * int) -> GenType<'a> -> Client // Comments tests
406 TypeWithSpace : ``type with spaces``
407 Nested : ((string * int) -> (*comment tests*) RequestData) -> Client
408 mutable Mutable : obj }
409
410let testRecordColoration =
411 { Firstname = "string" // Comments should work here
412 Lastname = "string"
413 Age = 10
414 Notify = fun _ -> ()
415 Notify2 = fun s -> ()
416 Notify3 = fun _ -> ()
417 Notify4 = fun _ -> ()
418 Callback = fun (a, (*b) comments should works here too*) b) -> unbox null
419 TypeWithSpace = null
420 Nested = fun func -> unbox null
421 Mutable = null }
422
423type CheckSingleLineRecord =
424 { Param1 : string; (*comment tests*) Param2 : obj }
425
426// Check that compression expression aren't mess up by the record coloration
427let a =
428 async {
429 let! a = async {
430 (*comment tests*)
431 return 0
432 }
433 return a
434 }
435
436// Test case for: https://github.com/ionide/ionide-fsgrammar/issues/147
437let testVariableWithModuleKeyword test_module =
438 if test_module then // This is the line where the problem is
439 ()
440
441// Edge cases provided by @selketjah
442// In this code some of the `type` word where colored in purple
443type Example =
444 { Type : int
445 SType : int
446 Stype : int
447 STypeT : int
448 StypeT : int // comments tests
449 TypeS : int (*comment tests*)
450 typeTest : int
451 stype : int
452 stypes : int
453 s_type : int }
454
455// Edge cases provided by @selketjah
456// `type` was colored as keyword
457// `with` as a Type declaration
458let temp (s : Example) =
459 match s.stype with
460 | 0 -> "whatever"
461 | 1 -> ""
462
463// Edge case when there is something after } the next type is not colored
464type One =
465 { Id : string } // test
466
467type Two =
468 { Id : int }
469
470// Support for anonymous records
471
472type Employee =
473 | Engineer of {| Prop1 : int; Prop2 : {| Prop1 : int; Prop2 : {| Prop1 : GenType<GenType<obj>>; Prop2 : {| Prop1 : int; Prop2 : List<string> |} |} |} |}
474 | Manager of {| Prop1 : int; Prop2 : {| Prop1 : int; Prop2 : List<string> |} |}
475
476let private standardIntInput (props : {| Dispatch : GenType<GenType<obj>>
477 Disabled : {| Prop1 : int; Prop2 : {| Prop1 : int; Prop2 : List<string> |} |}
478 Errors : GenType<'Msg> list |}) = ""
479
480let test = fun (props : {| Dispatch : GenType<GenType<obj>>
481 Disabled : {| Prop1 : int; Prop2 : {| Prop1 : int; Prop2 : List<string> |} |}
482 Errors : GenType<'Msg> list |}) -> ""
483
484type AR_Class () =
485 member this.Method1 (props : {| Dispatch : GenType<GenType<obj>>
486 Disabled : {| Prop1 : int; Prop2 : {| Prop1 : int; Prop2 : List<string> |} |}
487 Errors : GenType<'Msg> list |}) = ""
488
489// Check anonymous function type signature
490let tx = fun (t : ``type with spaces``) (``var with spaces`` : Result<obj list, int>) -> ()
491
492let private mixedArray msg (decoders: string []) (path: string) (values: obj[]): Result<obj list, int> =
493 Ok []
494
495type Auto() =
496 static let (color, message) = failwith ""
497
498 static let (color : Result<'T, string>) = failwith ""
499
500 // Here `<`& `>` not in purple
501 static member GenerateDecoder<'T> (?isCamelCase : bool): GenType<'T> = failwith ""
502
503 // Here generics not colored
504 static member FromString<'T>(json: string, ?isCamelCase : bool): 'T = failwith ""
505
506
507type Example1 = { Test : int list }
508let test = { Test = [ 1;2;3 ] }
509// test.test shouldn't be colored
510let temp = { test with Test = 3 :: test.Test }
511
512type EitherBuilder() =
513 member __.Bind(x) = x
514 member __.Return(x) = x
515
516let either = EitherBuilder()
517
518let test x =
519 // Ensure coloration is working correctly in custom computation expressions
520 either {
521 let x = x
522 let! c = ""
523
524 return 0
525 }
526
527open System
528
529type QueueTrigger(msg : string, b : bool) =
530 inherit Attribute()
531
532type [<AllowNullLiteral>] AppState2() =
533 class end
534
535type [<AllowNullLiteral>] AppState<'a, 'b>() =
536 class end
537
538let run ([<QueueTrigger("something", false); QueueTrigger("something", false)>] content:string) = failwith ""
539
540type [<QueueTrigger("something", false)>] TestInlineAttributeGenerics<'a, 'b>(content:string) =
541 class end
542
543type [<QueueTrigger("something", false)>] TestInlineAttribute(content:string) =
544 class end
545
546[<QueueTrigger("something", false); QueueTrigger("something", false)>]
547type TestAttribue2(content:string) =
548 class end
549
550// // Make sure coloration support SRTP synthax
551// // The next code has been copied from
552// // https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/generics/statically-resolved-type-parameters
553
554let inline konst x _ = x
555
556type CFunctor() =
557 static member inline fmap (f: ^a -> ^b, a: ^a list) = List.map f a
558 static member inline fmap (f: ^a -> ^b, a: ^a option) =
559 match a with
560 | None -> None
561 | Some x -> Some (f x)
562
563 // default implementation of replace
564 static member inline replace< ^a, ^b, ^c, ^d, ^e when ^a :> CFunctor and (^a or ^d): (static member fmap: (^b -> ^c) * ^d -> ^e) > (a, f) =
565 ((^a or ^d) : (static member fmap : (^b -> ^c) * ^d -> ^e) (konst a, f))
566
567 // call overridden replace if present
568 static member inline replace< ^a, ^b, ^c when ^b: (static member replace: ^a * ^b -> ^c)>(a: ^a, f: ^b) =
569 (^b : (static member replace: ^a * ^b -> ^c) (a, f))
570
571let inline replace_instance< ^a, ^b, ^c, ^d when (^a or ^c): (static member replace: ^b * ^c -> ^d)> (a: ^b, f: ^c) =
572 ((^a or ^c): (static member replace: ^b * ^c -> ^d) (a, f))
573
574// Note the concrete type 'CFunctor' specified in the signature
575let inline replace (a: ^a) (f: ^b): ^a0 when (CFunctor or ^b): (static member replace: ^a * ^b -> ^a0) =
576 replace_instance<CFunctor, _, _, _> (a, f)
577
578// End of SRTP synthax
579
580// Make sure constraints are correctly colored
581// https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/generics/constraints
582
583// Base Type Constraint
584type Class1<'T when 'T :> System.Exception> =
585 class end
586
587// Interface Type Constraint
588type Class2<'T when 'T :> System.IComparable> =
589 class end
590
591// Null constraint
592type Class3<'T when 'T : null> =
593 class end
594
595// Member constraint with static member
596type Class4<'T when 'T : (static member staticMethod1 : unit -> 'T) > =
597 class end
598
599// Member constraint with instance member
600type Class5<'T when 'T : (member Method1 : 'T -> int)> =
601 class end
602
603// Member constraint with property
604type Class6<'T when 'T : (member Property1 : int)> =
605 class end
606
607// Constructor constraint
608type Class7<'T when 'T : (new : unit -> 'T)>(thing:int, var2 : string -> string, ``ddzdz``: string list, extra) as xxx =
609 member val Field = new 'T()
610
611// Reference type constraint
612type Class8<'T when 'T : not struct> =
613 class end
614
615// Enumeration constraint with underlying value specified
616type Class9<'T when 'T : enum<uint32>> =
617 class end
618
619// 'T must implement IComparable, or be an array type with comparable
620// elements, or be System.IntPtr or System.UIntPtr. Also, 'T must not have
621// the NoComparison attribute.
622type Class10<'T when 'T : comparison> =
623 class end
624
625// 'T must support equality. This is true for any type that does not
626// have the NoEquality attribute.
627type Class11<'T when 'T : equality> =
628 class end
629
630type Class12<'T when 'T : delegate<obj * System.EventArgs, unit>> =
631 class end
632
633type Class13<'T when 'T : unmanaged> =
634 class end
635
636// Member constraints with two type parameters
637// Most often used with static type parameters in inline functions
638
639// Test that we are correctly detecting the end of the STRP syntahx when there is only one argument
640let inline doNothing(_value1 : ^T when ^T : (static member (+) : ^T * ^T -> ^T)) =
641 ""
642
643let inline doNothing(_value1 : ^Word when ^Word : (static member toJson : ^Word * ^Word -> ^Word)) =
644 ""
645
646let inline add2(value1 : ^T, value2: ^T when ^T : (static member (+) : ^T * ^T -> ^T)) =
647 value1 + value2
648
649let inline add(value1 : ^T when ^T : (static member (+) : ^T * ^T -> ^T), value2: ^T) =
650 value1 + value2
651
652// ^T and ^U must support operator +
653let inline heterogenousAdd(value1 : ^T when (^T or ^U) : (static member (+) : ^T * ^U -> ^T), value2 : ^U) =
654 value1 + value2
655
656let inline heterogenousAdd(value1 : ^Word when (^Word or ^U) : (static member (+) : ^Word * ^U -> ^Word), value2 : ^U) =
657 value1 + value2
658
659// If there are multiple constraints, use the and keyword to separate them.
660type Class14<'T,'U when 'T : equality and 'U : equality> =
661 class end
662
663type Class15<'``generic type with space`` when '``generic type with space`` :> System.Exception> =
664 class end
665
666// Type constrainst coloration also works in the constructor
667type Class16(value1 : ^T when (^T or ^U) : (static member (+) : ^T * ^U -> ^T), value2 : ^U) =
668 class end
669
670// Make sure that `:>` isn't closing the current generic tag
671let inline create<'a, 'b when 'a :> obj and 'a: (new: unit -> 'a)> () : 'b = failwith ""
672
673// Explicit Fields
674// Adapted from: https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/members/explicit-fields-the-val-keyword
675// And : https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/members/let-bindings-in-classes
676
677type MyType<'``Generic type with spaces``, 'T>() =
678 let mutable myInt1 = 10
679 static let mutable myInt3 = 3
680 [<DefaultValue>] static val mutable private myInt2 : int
681 [<DefaultValue>] val mutable myString : '``Generic type with spaces``
682 [<DefaultValue>] val mutable myString2 : 'T
683
684type MyClass =
685 val a : int
686 val b : int
687 // The following version of the constructor is an error
688 // because b is not initialized.
689 // new (a0, b0) = { a = a0; }
690 // The following version is acceptable because all fields are initialized.
691 new(a0, b0) = { a = a0; b = b0; }
692
693// Check that SRTP do not break standard syntax between `(` & `)`
694let incorrect =
695 (fun loadedModel ->
696 let temp = async {
697 return 0
698 }
699 let loadedModel = { loadedModel with FormState = Form.setWaiting false loadedModel.FormState }
700 ())
View as plain text