elm-pages 2.1.10 → 3.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmi +0 -0
  2. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmo +0 -0
  3. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmi +0 -0
  4. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmo +0 -0
  5. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolationsTest.elmi +0 -0
  6. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolationsTest.elmo +0 -0
  7. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Reporter.elmi +0 -0
  8. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Reporter.elmo +0 -0
  9. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Runner.elmi +0 -0
  10. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Runner.elmo +0 -0
  11. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  12. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  13. package/generator/{template/public/style.css → review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/lock} +0 -0
  14. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  15. package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -0
  16. package/generator/review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +6795 -0
  17. package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +27617 -0
  18. package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +110 -0
  19. package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +187 -0
  20. package/generator/review/elm-stuff/tests-0.19.1/js/package.json +1 -0
  21. package/generator/review/elm-stuff/tests-0.19.1/src/Reporter.elm +26 -0
  22. package/generator/review/elm-stuff/tests-0.19.1/src/Runner.elm +62 -0
  23. package/generator/review/elm.json +13 -4
  24. package/{src → generator/review/src}/Pages/Review/NoContractViolations.elm +148 -148
  25. package/generator/review/tests/Pages/Review/NoContractViolationsTest.elm +331 -0
  26. package/generator/src/RouteBuilder.elm +420 -0
  27. package/generator/src/SharedTemplate.elm +4 -5
  28. package/generator/src/SiteConfig.elm +3 -9
  29. package/generator/src/build.js +308 -95
  30. package/generator/src/cli.js +103 -8
  31. package/generator/src/codegen.js +192 -35
  32. package/generator/src/compile-elm.js +183 -31
  33. package/generator/src/dev-server.js +353 -96
  34. package/generator/src/elm-application.json +3 -1
  35. package/generator/src/elm-codegen.js +34 -0
  36. package/generator/src/elm-file-constants.js +2 -0
  37. package/generator/src/error-formatter.js +20 -1
  38. package/generator/src/generate-template-module-connector.js +120 -924
  39. package/generator/src/hello.ts +5 -0
  40. package/generator/src/pre-render-html.js +58 -104
  41. package/generator/src/render-worker.js +27 -13
  42. package/generator/src/render.js +252 -197
  43. package/generator/src/request-cache-fs.js +18 -0
  44. package/generator/src/request-cache.js +128 -56
  45. package/generator/src/rewrite-client-elm-json.js +49 -0
  46. package/generator/src/route-codegen-helpers.js +62 -1
  47. package/generator/static-code/dev-style.css +22 -0
  48. package/generator/static-code/elm-pages.js +43 -39
  49. package/generator/static-code/hmr.js +98 -88
  50. package/generator/template/app/Api.elm +25 -0
  51. package/generator/template/app/ErrorPage.elm +38 -0
  52. package/generator/template/app/Route/Index.elm +87 -0
  53. package/generator/template/{src → app}/Shared.elm +34 -13
  54. package/generator/template/app/Site.elm +19 -0
  55. package/generator/template/{src → app}/View.elm +0 -0
  56. package/generator/template/elm-pages.config.mjs +5 -0
  57. package/generator/template/elm.json +14 -5
  58. package/generator/template/{public/index.js → index.ts} +7 -3
  59. package/generator/template/package.json +5 -5
  60. package/generator/template/public/favicon.ico +0 -0
  61. package/generator/template/public/images/icon-png.png +0 -0
  62. package/generator/template/src/.gitkeep +0 -0
  63. package/generator/template/style.css +4 -0
  64. package/package.json +30 -23
  65. package/src/ApiRoute.elm +176 -43
  66. package/src/BuildError.elm +10 -1
  67. package/src/CookieParser.elm +84 -0
  68. package/src/DataSource/Env.elm +38 -0
  69. package/src/DataSource/File.elm +27 -16
  70. package/src/DataSource/Glob.elm +126 -80
  71. package/src/DataSource/Http.elm +283 -304
  72. package/src/DataSource/Internal/Glob.elm +5 -21
  73. package/src/DataSource/Internal/Request.elm +25 -0
  74. package/src/DataSource/Port.elm +17 -14
  75. package/src/DataSource.elm +55 -318
  76. package/src/Form/Field.elm +717 -0
  77. package/src/Form/FieldStatus.elm +36 -0
  78. package/src/Form/FieldView.elm +417 -0
  79. package/src/Form/FormData.elm +22 -0
  80. package/src/Form/Validation.elm +391 -0
  81. package/src/Form/Value.elm +118 -0
  82. package/src/Form.elm +1683 -0
  83. package/src/FormData.elm +58 -0
  84. package/src/FormDecoder.elm +102 -0
  85. package/src/Head/Seo.elm +12 -4
  86. package/src/Head.elm +12 -2
  87. package/src/HtmlPrinter.elm +1 -1
  88. package/src/Internal/ApiRoute.elm +17 -4
  89. package/src/Internal/Request.elm +7 -0
  90. package/src/PageServerResponse.elm +68 -0
  91. package/src/Pages/ContentCache.elm +1 -229
  92. package/src/Pages/Fetcher.elm +58 -0
  93. package/src/Pages/FormState.elm +256 -0
  94. package/src/Pages/Generate.elm +800 -0
  95. package/src/Pages/Internal/Form.elm +17 -0
  96. package/src/Pages/Internal/NotFoundReason.elm +3 -55
  97. package/src/Pages/Internal/Platform/Cli.elm +777 -579
  98. package/src/Pages/Internal/Platform/Effect.elm +5 -5
  99. package/src/Pages/Internal/Platform/StaticResponses.elm +178 -394
  100. package/src/Pages/Internal/Platform/ToJsPayload.elm +24 -23
  101. package/src/Pages/Internal/Platform.elm +1244 -504
  102. package/src/Pages/Internal/ResponseSketch.elm +19 -0
  103. package/src/Pages/Internal/RoutePattern.elm +596 -45
  104. package/src/Pages/Manifest.elm +26 -0
  105. package/src/Pages/Msg.elm +79 -0
  106. package/src/Pages/ProgramConfig.elm +67 -14
  107. package/src/Pages/SiteConfig.elm +3 -6
  108. package/src/Pages/StaticHttp/Request.elm +4 -2
  109. package/src/Pages/StaticHttpRequest.elm +50 -215
  110. package/src/Pages/Transition.elm +70 -0
  111. package/src/Path.elm +1 -0
  112. package/src/Pattern.elm +98 -0
  113. package/src/RenderRequest.elm +2 -2
  114. package/src/RequestsAndPending.elm +111 -9
  115. package/src/Server/Request.elm +1253 -0
  116. package/src/Server/Response.elm +292 -0
  117. package/src/Server/Session.elm +316 -0
  118. package/src/Server/SetCookie.elm +169 -0
  119. package/src/TerminalText.elm +1 -1
  120. package/src/Test/Html/Internal/ElmHtml/Markdown.elm +0 -1
  121. package/src/Test/Html/Internal/ElmHtml/ToString.elm +1 -1
  122. package/generator/src/Page.elm +0 -359
  123. package/generator/src/codegen-template-module.js +0 -183
  124. package/generator/src/elm-pages-js-minified.js +0 -1
  125. package/generator/template/src/Api.elm +0 -14
  126. package/generator/template/src/Page/Index.elm +0 -69
  127. package/generator/template/src/Site.elm +0 -41
  128. package/src/DataSource/ServerRequest.elm +0 -60
  129. package/src/Internal/OptimizedDecoder.elm +0 -18
  130. package/src/KeepOrDiscard.elm +0 -6
  131. package/src/OptimizedDecoder/Pipeline.elm +0 -335
  132. package/src/OptimizedDecoder.elm +0 -818
  133. package/src/Pages/Internal/ApplicationType.elm +0 -6
  134. package/src/Pages/Secrets.elm +0 -83
  135. package/src/Secrets.elm +0 -111
  136. package/src/SecretsDict.elm +0 -45
@@ -6,9 +6,12 @@ module DataSource.Glob exposing
6
6
  , int, digits
7
7
  , expectUniqueMatch, expectUniqueMatchFromList
8
8
  , literal
9
- , map, succeed, toDataSource
9
+ , map, succeed
10
10
  , oneOf
11
11
  , zeroOrMore, atLeastOne
12
+ , toDataSource
13
+ , toDataSourceWithOptions
14
+ , defaultOptions, Options, Include(..)
12
15
  )
13
16
 
14
17
  {-|
@@ -152,7 +155,7 @@ This is my first post!
152
155
  Then we could read that title for our blog post list page using our `blogPosts` `DataSource` that we defined above.
153
156
 
154
157
  import DataSource.File
155
- import OptimizedDecoder as Decode exposing (Decoder)
158
+ import Json.Decode as Decode exposing (Decoder)
156
159
 
157
160
  titles : DataSource (List BlogPost)
158
161
  titles =
@@ -202,21 +205,33 @@ That will give us
202
205
 
203
206
  @docs literal
204
207
 
205
- @docs map, succeed, toDataSource
208
+ @docs map, succeed
206
209
 
207
210
  @docs oneOf
208
211
 
209
212
  @docs zeroOrMore, atLeastOne
210
213
 
214
+
215
+ ## Getting Glob Data from a DataSource
216
+
217
+ @docs toDataSource
218
+
219
+
220
+ ### With Custom Options
221
+
222
+ @docs toDataSourceWithOptions
223
+
224
+ @docs defaultOptions, Options, Include
225
+
211
226
  -}
212
227
 
213
228
  import DataSource exposing (DataSource)
214
229
  import DataSource.Http
215
230
  import DataSource.Internal.Glob exposing (Glob(..))
231
+ import DataSource.Internal.Request
232
+ import Json.Decode as Decode
233
+ import Json.Encode as Encode
216
234
  import List.Extra
217
- import OptimizedDecoder
218
- import Regex
219
- import Secrets
220
235
 
221
236
 
222
237
  {-| A pattern to match local files and capture parts of the path into a nice Elm data type.
@@ -276,9 +291,8 @@ For example, you could take a date and parse it.
276
291
 
277
292
  -}
278
293
  map : (a -> b) -> Glob a -> Glob b
279
- map mapFn (Glob pattern regex applyCapture) =
294
+ map mapFn (Glob pattern applyCapture) =
280
295
  Glob pattern
281
- regex
282
296
  (\fullPath captures ->
283
297
  captures
284
298
  |> applyCapture fullPath
@@ -290,13 +304,12 @@ map mapFn (Glob pattern regex applyCapture) =
290
304
  -}
291
305
  succeed : constructor -> Glob constructor
292
306
  succeed constructor =
293
- Glob "" "" (\_ captures -> ( constructor, captures ))
307
+ Glob "" (\_ captures -> ( constructor, captures ))
294
308
 
295
309
 
296
310
  fullFilePath : Glob String
297
311
  fullFilePath =
298
312
  Glob ""
299
- ""
300
313
  (\fullPath captures ->
301
314
  ( fullPath, captures )
302
315
  )
@@ -394,7 +407,6 @@ will match _within_ a path part (think between the slashes of a file path). `rec
394
407
  wildcard : Glob String
395
408
  wildcard =
396
409
  Glob "*"
397
- wildcardRegex
398
410
  (\_ captures ->
399
411
  case captures of
400
412
  first :: rest ->
@@ -405,11 +417,6 @@ wildcard =
405
417
  )
406
418
 
407
419
 
408
- wildcardRegex : String
409
- wildcardRegex =
410
- "([^/]*?)"
411
-
412
-
413
420
  {-| This is similar to [`wildcard`](#wildcard), but it will only match 1 or more digits (i.e. `[0-9]+`).
414
421
 
415
422
  See [`int`](#int) for a convenience function to get an Int value instead of a String of digits.
@@ -417,8 +424,7 @@ See [`int`](#int) for a convenience function to get an Int value instead of a St
417
424
  -}
418
425
  digits : Glob String
419
426
  digits =
420
- Glob "[0-9]+"
421
- "([0-9]+?)"
427
+ Glob "([0-9]+)"
422
428
  (\_ captures ->
423
429
  case captures of
424
430
  first :: rest ->
@@ -564,7 +570,6 @@ This is usually not what is intended. Using `recursiveWildcard` is usually follo
564
570
  recursiveWildcard : Glob (List String)
565
571
  recursiveWildcard =
566
572
  Glob "**"
567
- recursiveWildcardRegex
568
573
  (\_ captures ->
569
574
  case captures of
570
575
  first :: rest ->
@@ -577,11 +582,6 @@ recursiveWildcard =
577
582
  |> map (List.filter (not << String.isEmpty))
578
583
 
579
584
 
580
- recursiveWildcardRegex : String
581
- recursiveWildcardRegex =
582
- "(.*?)"
583
-
584
-
585
585
  {-| -}
586
586
  zeroOrMore : List String -> Glob (Maybe String)
587
587
  zeroOrMore matchers =
@@ -590,10 +590,6 @@ zeroOrMore matchers =
590
590
  ++ (matchers |> String.join "|")
591
591
  ++ ")"
592
592
  )
593
- ("((?:"
594
- ++ (matchers |> List.map regexEscaped |> String.join "|")
595
- ++ ")*)"
596
- )
597
593
  (\_ captures ->
598
594
  case captures of
599
595
  first :: rest ->
@@ -637,21 +633,7 @@ blogPosts =
637
633
  -}
638
634
  literal : String -> Glob String
639
635
  literal string =
640
- Glob string (regexEscaped string) (\_ captures -> ( string, captures ))
641
-
642
-
643
- regexEscaped : String -> String
644
- regexEscaped stringLiteral =
645
- --https://stackoverflow.com/a/6969486
646
- stringLiteral
647
- |> Regex.replace regexEscapePattern (\match_ -> "\\" ++ match_.match)
648
-
649
-
650
- regexEscapePattern : Regex.Regex
651
- regexEscapePattern =
652
- "[.*+?^${}()|[\\]\\\\]"
653
- |> Regex.fromString
654
- |> Maybe.withDefault Regex.never
636
+ Glob string (\_ captures -> ( string, captures ))
655
637
 
656
638
 
657
639
  {-| Adds on to the glob pattern, but does not capture it in the resulting Elm match value. That means this changes which
@@ -661,10 +643,9 @@ Exactly the same as `capture` except it doesn't capture the matched sub-pattern.
661
643
 
662
644
  -}
663
645
  match : Glob a -> Glob value -> Glob value
664
- match (Glob matcherPattern regex1 apply1) (Glob pattern regex2 apply2) =
646
+ match (Glob matcherPattern apply1) (Glob pattern apply2) =
665
647
  Glob
666
648
  (pattern ++ matcherPattern)
667
- (combineRegexes regex1 regex2)
668
649
  (\fullPath captures ->
669
650
  let
670
651
  ( _, captured1 ) =
@@ -730,10 +711,9 @@ you can pick apart structured data as you build up your glob pattern. This follo
730
711
 
731
712
  -}
732
713
  capture : Glob a -> Glob (a -> value) -> Glob value
733
- capture (Glob matcherPattern regex1 apply1) (Glob pattern regex2 apply2) =
714
+ capture (Glob matcherPattern apply1) (Glob pattern apply2) =
734
715
  Glob
735
716
  (pattern ++ matcherPattern)
736
- (combineRegexes regex1 regex2)
737
717
  (\fullPath captures ->
738
718
  let
739
719
  ( applied1, captured1 ) =
@@ -750,21 +730,6 @@ capture (Glob matcherPattern regex1 apply1) (Glob pattern regex2 apply2) =
750
730
  )
751
731
 
752
732
 
753
- combineRegexes : String -> String -> String
754
- combineRegexes regex1 regex2 =
755
- if isRecursiveWildcardSlashWildcard regex1 regex2 then
756
- (regex2 |> String.dropRight 1) ++ regex1
757
-
758
- else
759
- regex2 ++ regex1
760
-
761
-
762
- isRecursiveWildcardSlashWildcard : String -> String -> Bool
763
- isRecursiveWildcardSlashWildcard regex1 regex2 =
764
- (regex2 |> String.endsWith (recursiveWildcardRegex ++ "/"))
765
- && (regex1 |> String.startsWith wildcardRegex)
766
-
767
-
768
733
  {-|
769
734
 
770
735
  import DataSource.Glob as Glob
@@ -860,13 +825,6 @@ oneOf ( defaultMatch, otherMatchers ) =
860
825
  ++ (allMatchers |> List.map Tuple.first |> String.join ",")
861
826
  ++ "}"
862
827
  )
863
- ("("
864
- ++ String.join "|"
865
- ((allMatchers |> List.map Tuple.first |> List.map regexEscaped)
866
- |> List.map regexEscaped
867
- )
868
- ++ ")"
869
- )
870
828
  (\_ captures ->
871
829
  case captures of
872
830
  match_ :: rest ->
@@ -901,10 +859,6 @@ atLeastOne ( defaultMatch, otherMatchers ) =
901
859
  ++ (allMatchers |> List.map Tuple.first |> String.join "|")
902
860
  ++ ")"
903
861
  )
904
- ("((?:"
905
- ++ (allMatchers |> List.map Tuple.first |> List.map regexEscaped |> String.join "|")
906
- ++ ")+)"
907
- )
908
862
  (\_ captures ->
909
863
  case captures of
910
864
  match_ :: rest ->
@@ -944,12 +898,104 @@ toNonEmptyWithDefault default list =
944
898
  -}
945
899
  toDataSource : Glob a -> DataSource (List a)
946
900
  toDataSource glob =
947
- DataSource.Http.get (Secrets.succeed <| "glob://" ++ DataSource.Internal.Glob.toPattern glob)
948
- (OptimizedDecoder.string
949
- |> OptimizedDecoder.list
950
- |> OptimizedDecoder.map
951
- (\rawGlob -> rawGlob |> List.map (\matchedPath -> DataSource.Internal.Glob.run matchedPath glob |> .match))
952
- )
901
+ toDataSourceWithOptions defaultOptions glob
902
+
903
+
904
+ {-| <https://github.com/mrmlnc/fast-glob#onlyfiles>
905
+
906
+ <https://github.com/mrmlnc/fast-glob#onlydirectories>
907
+
908
+ -}
909
+ type Include
910
+ = OnlyFiles
911
+ | OnlyFolders
912
+ | FilesAndFolders
913
+
914
+
915
+ {-| Custom options you can pass in to run the glob with [`toDataSourceWithOptions`](#toDataSourceWithOptions).
916
+
917
+ { includeDotFiles = Bool -- https://github.com/mrmlnc/fast-glob#dot
918
+ , include = Include -- return results that are `OnlyFiles`, `OnlyFolders`, or both `FilesAndFolders` (default is `OnlyFiles`)
919
+ , followSymbolicLinks = Bool -- https://github.com/mrmlnc/fast-glob#followsymboliclinks
920
+ , caseSensitiveMatch = Bool -- https://github.com/mrmlnc/fast-glob#casesensitivematch
921
+ , gitignore = Bool -- https://www.npmjs.com/package/globby#gitignore
922
+ , maxDepth = Maybe Int -- https://github.com/mrmlnc/fast-glob#deep
923
+ }
924
+
925
+ -}
926
+ type alias Options =
927
+ { includeDotFiles : Bool -- https://github.com/mrmlnc/fast-glob#dot
928
+ , include : Include
929
+ , followSymbolicLinks : Bool -- https://github.com/mrmlnc/fast-glob#followsymboliclinks
930
+ , caseSensitiveMatch : Bool -- https://github.com/mrmlnc/fast-glob#casesensitivematch
931
+ , gitignore : Bool -- https://www.npmjs.com/package/globby#gitignore
932
+ , maxDepth : Maybe Int -- https://github.com/mrmlnc/fast-glob#deep
933
+ }
934
+
935
+
936
+ {-| The default options used in [`toDataSource`](#toDataSource). To use a custom set of options, use [`toDataSourceWithOptions`](#toDataSourceWithOptions).
937
+ -}
938
+ defaultOptions : Options
939
+ defaultOptions =
940
+ { includeDotFiles = False
941
+ , followSymbolicLinks = True
942
+ , caseSensitiveMatch = True
943
+ , gitignore = False
944
+ , maxDepth = Nothing
945
+ , include = OnlyFiles
946
+ }
947
+
948
+
949
+ encodeOptions : Options -> Encode.Value
950
+ encodeOptions options =
951
+ [ ( "dot", Encode.bool options.includeDotFiles ) |> Just
952
+ , ( "followSymbolicLinks", Encode.bool options.followSymbolicLinks ) |> Just
953
+ , ( "caseSensitiveMatch", Encode.bool options.caseSensitiveMatch ) |> Just
954
+ , ( "gitignore", Encode.bool options.gitignore ) |> Just
955
+ , options.maxDepth |> Maybe.map (\depth -> ( "deep", Encode.int depth ))
956
+ , ( "onlyFiles", options.include == OnlyFiles || options.include == FilesAndFolders |> Encode.bool ) |> Just
957
+ , ( "onlyDirectories", options.include == OnlyFolders || options.include == FilesAndFolders |> Encode.bool ) |> Just
958
+ ]
959
+ |> List.filterMap identity
960
+ |> Encode.object
961
+
962
+
963
+ {-| Same as toDataSource, but lets you set custom glob options. For example, to list folders instead of files,
964
+
965
+ import DataSource.Glob as Glob exposing (OnlyFolders, defaultOptions)
966
+
967
+ matchingFiles : Glob a -> DataSource (List a)
968
+ matchingFiles glob =
969
+ glob
970
+ |> Glob.toDataSourceWithOptions { defaultOptions | include = OnlyFolders }
971
+
972
+ -}
973
+ toDataSourceWithOptions : Options -> Glob a -> DataSource (List a)
974
+ toDataSourceWithOptions options glob =
975
+ DataSource.Internal.Request.request
976
+ { name = "glob"
977
+ , body =
978
+ Encode.object
979
+ [ ( "pattern", Encode.string <| DataSource.Internal.Glob.toPattern glob )
980
+ , ( "options", encodeOptions options )
981
+ ]
982
+ |> DataSource.Http.jsonBody
983
+ , expect =
984
+ Decode.map2 (\fullPath captures -> { fullPath = fullPath, captures = captures })
985
+ (Decode.field "fullPath" Decode.string)
986
+ (Decode.field "captures" (Decode.list Decode.string))
987
+ |> Decode.list
988
+ |> Decode.map
989
+ (\rawGlob ->
990
+ rawGlob
991
+ |> List.map
992
+ (\{ fullPath, captures } ->
993
+ DataSource.Internal.Glob.run fullPath captures glob
994
+ |> .match
995
+ )
996
+ )
997
+ |> DataSource.Http.expectJson
998
+ }
953
999
 
954
1000
 
955
1001
  {-| Sometimes you want to make sure there is a unique file matching a particular pattern.
@@ -1046,5 +1092,5 @@ expectUniqueMatchFromList globs =
1046
1092
  toPatternString : Glob a -> String
1047
1093
  toPatternString glob =
1048
1094
  case glob of
1049
- Glob pattern_ _ _ ->
1095
+ Glob pattern_ _ ->
1050
1096
  pattern_