diff --git a/fml-parser/FmlMapping.g4 b/fml-parser/FmlMapping.g4 index 5d52a775..f1e1c26b 100644 --- a/fml-parser/FmlMapping.g4 +++ b/fml-parser/FmlMapping.g4 @@ -38,7 +38,7 @@ code ; mapDeclaration - : 'map' url '=' identifier + : 'map' url '=' (identifier | DOUBLE_QUOTED_STRING) // double quoting is a legacy format, and tollerant of content handled by the HAPI engine ; metadataDeclaration diff --git a/fml-parser/FmlMapping.interp b/fml-parser/FmlMapping.interp index 699512f0..708d7da7 100644 --- a/fml-parser/FmlMapping.interp +++ b/fml-parser/FmlMapping.interp @@ -278,4 +278,4 @@ fpQuantity atn: -[4, 1, 106, 587, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 1, 0, 5, 0, 118, 8, 0, 10, 0, 12, 0, 121, 9, 0, 1, 0, 5, 0, 124, 8, 0, 10, 0, 12, 0, 127, 9, 0, 1, 0, 3, 0, 130, 8, 0, 1, 0, 5, 0, 133, 8, 0, 10, 0, 12, 0, 136, 9, 0, 1, 0, 5, 0, 139, 8, 0, 10, 0, 12, 0, 142, 9, 0, 1, 0, 5, 0, 145, 8, 0, 10, 0, 12, 0, 148, 9, 0, 1, 0, 4, 0, 151, 8, 0, 11, 0, 12, 0, 152, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 161, 8, 1, 11, 1, 12, 1, 162, 1, 1, 4, 1, 166, 8, 1, 11, 1, 12, 1, 167, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 201, 8, 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 3, 12, 213, 8, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 3, 14, 228, 8, 14, 1, 14, 3, 14, 231, 8, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 4, 15, 239, 8, 15, 11, 15, 12, 15, 240, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 3, 16, 248, 8, 16, 1, 17, 1, 17, 5, 17, 252, 8, 17, 10, 17, 12, 17, 255, 9, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 3, 21, 273, 8, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 3, 21, 280, 8, 21, 1, 22, 1, 22, 1, 22, 3, 22, 285, 8, 22, 1, 22, 3, 22, 288, 8, 22, 1, 22, 3, 22, 291, 8, 22, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 5, 24, 298, 8, 24, 10, 24, 12, 24, 301, 9, 24, 1, 25, 1, 25, 3, 25, 305, 8, 25, 1, 25, 3, 25, 308, 8, 25, 1, 25, 3, 25, 311, 8, 25, 1, 25, 3, 25, 314, 8, 25, 1, 25, 3, 25, 317, 8, 25, 1, 25, 3, 25, 320, 8, 25, 1, 25, 3, 25, 323, 8, 25, 1, 25, 3, 25, 326, 8, 25, 1, 26, 1, 26, 1, 26, 5, 26, 331, 8, 26, 10, 26, 12, 26, 334, 9, 26, 1, 27, 1, 27, 1, 27, 3, 27, 339, 8, 27, 1, 27, 3, 27, 342, 8, 27, 1, 27, 3, 27, 345, 8, 27, 1, 27, 1, 27, 1, 27, 1, 27, 3, 27, 351, 8, 27, 1, 27, 3, 27, 354, 8, 27, 1, 27, 1, 27, 3, 27, 358, 8, 27, 3, 27, 360, 8, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 5, 30, 371, 8, 30, 10, 30, 12, 30, 374, 9, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 3, 31, 383, 8, 31, 1, 32, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 5, 36, 407, 8, 36, 10, 36, 12, 36, 410, 9, 36, 1, 36, 3, 36, 413, 8, 36, 1, 36, 3, 36, 416, 8, 36, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 3, 38, 428, 8, 38, 1, 39, 1, 39, 1, 39, 3, 39, 433, 8, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 5, 40, 440, 8, 40, 10, 40, 12, 40, 443, 9, 40, 1, 41, 1, 41, 3, 41, 447, 8, 41, 1, 42, 1, 42, 1, 42, 1, 42, 3, 42, 453, 8, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 5, 42, 493, 8, 42, 10, 42, 12, 42, 496, 9, 42, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 3, 43, 505, 8, 43, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 3, 44, 512, 8, 44, 1, 45, 1, 45, 1, 45, 3, 45, 517, 8, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 5, 46, 524, 8, 46, 10, 46, 12, 46, 527, 9, 46, 3, 46, 529, 8, 46, 1, 46, 1, 46, 1, 46, 1, 46, 3, 46, 535, 8, 46, 1, 46, 1, 46, 3, 46, 539, 8, 46, 1, 47, 1, 47, 3, 47, 543, 8, 47, 1, 48, 1, 48, 1, 48, 5, 48, 548, 8, 48, 10, 48, 12, 48, 551, 9, 48, 1, 49, 1, 49, 1, 50, 1, 50, 1, 51, 1, 51, 1, 52, 1, 52, 1, 53, 1, 53, 1, 54, 1, 54, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 3, 56, 577, 8, 56, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 3, 57, 585, 8, 57, 1, 57, 5, 119, 125, 134, 140, 146, 1, 84, 58, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 0, 22, 2, 0, 97, 97, 100, 101, 1, 0, 100, 101, 2, 0, 9, 15, 97, 99, 2, 0, 29, 29, 96, 96, 7, 0, 4, 4, 8, 10, 12, 18, 20, 20, 26, 26, 30, 38, 97, 98, 2, 0, 6, 6, 45, 45, 3, 0, 29, 29, 36, 36, 46, 47, 3, 0, 6, 6, 45, 45, 48, 48, 1, 0, 50, 53, 2, 0, 5, 5, 54, 56, 1, 0, 10, 11, 1, 0, 58, 59, 2, 0, 9, 9, 12, 12, 1, 0, 13, 14, 2, 0, 37, 38, 65, 67, 2, 0, 37, 38, 68, 69, 2, 0, 33, 33, 70, 70, 2, 0, 31, 32, 71, 72, 1, 0, 31, 32, 1, 0, 95, 96, 1, 0, 73, 80, 1, 0, 81, 88, 617, 0, 119, 1, 0, 0, 0, 2, 156, 1, 0, 0, 0, 4, 171, 1, 0, 0, 0, 6, 176, 1, 0, 0, 0, 8, 180, 1, 0, 0, 0, 10, 184, 1, 0, 0, 0, 12, 188, 1, 0, 0, 0, 14, 190, 1, 0, 0, 0, 16, 195, 1, 0, 0, 0, 18, 202, 1, 0, 0, 0, 20, 204, 1, 0, 0, 0, 22, 206, 1, 0, 0, 0, 24, 208, 1, 0, 0, 0, 26, 217, 1, 0, 0, 0, 28, 223, 1, 0, 0, 0, 30, 234, 1, 0, 0, 0, 32, 244, 1, 0, 0, 0, 34, 249, 1, 0, 0, 0, 36, 258, 1, 0, 0, 0, 38, 262, 1, 0, 0, 0, 40, 265, 1, 0, 0, 0, 42, 279, 1, 0, 0, 0, 44, 281, 1, 0, 0, 0, 46, 292, 1, 0, 0, 0, 48, 294, 1, 0, 0, 0, 50, 302, 1, 0, 0, 0, 52, 327, 1, 0, 0, 0, 54, 359, 1, 0, 0, 0, 56, 361, 1, 0, 0, 0, 58, 365, 1, 0, 0, 0, 60, 367, 1, 0, 0, 0, 62, 382, 1, 0, 0, 0, 64, 384, 1, 0, 0, 0, 66, 387, 1, 0, 0, 0, 68, 392, 1, 0, 0, 0, 70, 397, 1, 0, 0, 0, 72, 402, 1, 0, 0, 0, 74, 417, 1, 0, 0, 0, 76, 427, 1, 0, 0, 0, 78, 429, 1, 0, 0, 0, 80, 436, 1, 0, 0, 0, 82, 446, 1, 0, 0, 0, 84, 452, 1, 0, 0, 0, 86, 504, 1, 0, 0, 0, 88, 511, 1, 0, 0, 0, 90, 513, 1, 0, 0, 0, 92, 538, 1, 0, 0, 0, 94, 540, 1, 0, 0, 0, 96, 544, 1, 0, 0, 0, 98, 552, 1, 0, 0, 0, 100, 554, 1, 0, 0, 0, 102, 556, 1, 0, 0, 0, 104, 558, 1, 0, 0, 0, 106, 560, 1, 0, 0, 0, 108, 562, 1, 0, 0, 0, 110, 564, 1, 0, 0, 0, 112, 576, 1, 0, 0, 0, 114, 584, 1, 0, 0, 0, 116, 118, 3, 16, 8, 0, 117, 116, 1, 0, 0, 0, 118, 121, 1, 0, 0, 0, 119, 120, 1, 0, 0, 0, 119, 117, 1, 0, 0, 0, 120, 125, 1, 0, 0, 0, 121, 119, 1, 0, 0, 0, 122, 124, 3, 2, 1, 0, 123, 122, 1, 0, 0, 0, 124, 127, 1, 0, 0, 0, 125, 126, 1, 0, 0, 0, 125, 123, 1, 0, 0, 0, 126, 129, 1, 0, 0, 0, 127, 125, 1, 0, 0, 0, 128, 130, 3, 14, 7, 0, 129, 128, 1, 0, 0, 0, 129, 130, 1, 0, 0, 0, 130, 134, 1, 0, 0, 0, 131, 133, 3, 24, 12, 0, 132, 131, 1, 0, 0, 0, 133, 136, 1, 0, 0, 0, 134, 135, 1, 0, 0, 0, 134, 132, 1, 0, 0, 0, 135, 140, 1, 0, 0, 0, 136, 134, 1, 0, 0, 0, 137, 139, 3, 74, 37, 0, 138, 137, 1, 0, 0, 0, 139, 142, 1, 0, 0, 0, 140, 141, 1, 0, 0, 0, 140, 138, 1, 0, 0, 0, 141, 146, 1, 0, 0, 0, 142, 140, 1, 0, 0, 0, 143, 145, 3, 26, 13, 0, 144, 143, 1, 0, 0, 0, 145, 148, 1, 0, 0, 0, 146, 147, 1, 0, 0, 0, 146, 144, 1, 0, 0, 0, 147, 150, 1, 0, 0, 0, 148, 146, 1, 0, 0, 0, 149, 151, 3, 28, 14, 0, 150, 149, 1, 0, 0, 0, 151, 152, 1, 0, 0, 0, 152, 150, 1, 0, 0, 0, 152, 153, 1, 0, 0, 0, 153, 154, 1, 0, 0, 0, 154, 155, 5, 0, 0, 1, 155, 1, 1, 0, 0, 0, 156, 157, 5, 1, 0, 0, 157, 158, 3, 20, 10, 0, 158, 160, 5, 2, 0, 0, 159, 161, 3, 4, 2, 0, 160, 159, 1, 0, 0, 0, 161, 162, 1, 0, 0, 0, 162, 160, 1, 0, 0, 0, 162, 163, 1, 0, 0, 0, 163, 165, 1, 0, 0, 0, 164, 166, 3, 6, 3, 0, 165, 164, 1, 0, 0, 0, 166, 167, 1, 0, 0, 0, 167, 165, 1, 0, 0, 0, 167, 168, 1, 0, 0, 0, 168, 169, 1, 0, 0, 0, 169, 170, 5, 3, 0, 0, 170, 3, 1, 0, 0, 0, 171, 172, 5, 4, 0, 0, 172, 173, 5, 97, 0, 0, 173, 174, 5, 5, 0, 0, 174, 175, 3, 20, 10, 0, 175, 5, 1, 0, 0, 0, 176, 177, 3, 8, 4, 0, 177, 178, 5, 6, 0, 0, 178, 179, 3, 10, 5, 0, 179, 7, 1, 0, 0, 0, 180, 181, 5, 97, 0, 0, 181, 182, 5, 7, 0, 0, 182, 183, 3, 12, 6, 0, 183, 9, 1, 0, 0, 0, 184, 185, 5, 97, 0, 0, 185, 186, 5, 7, 0, 0, 186, 187, 3, 12, 6, 0, 187, 11, 1, 0, 0, 0, 188, 189, 7, 0, 0, 0, 189, 13, 1, 0, 0, 0, 190, 191, 5, 8, 0, 0, 191, 192, 3, 20, 10, 0, 192, 193, 5, 5, 0, 0, 193, 194, 3, 22, 11, 0, 194, 15, 1, 0, 0, 0, 195, 196, 5, 105, 0, 0, 196, 197, 3, 60, 30, 0, 197, 200, 5, 5, 0, 0, 198, 201, 3, 112, 56, 0, 199, 201, 3, 18, 9, 0, 200, 198, 1, 0, 0, 0, 200, 199, 1, 0, 0, 0, 200, 201, 1, 0, 0, 0, 201, 17, 1, 0, 0, 0, 202, 203, 5, 102, 0, 0, 203, 19, 1, 0, 0, 0, 204, 205, 7, 1, 0, 0, 205, 21, 1, 0, 0, 0, 206, 207, 7, 2, 0, 0, 207, 23, 1, 0, 0, 0, 208, 209, 5, 16, 0, 0, 209, 212, 3, 20, 10, 0, 210, 211, 5, 17, 0, 0, 211, 213, 3, 22, 11, 0, 212, 210, 1, 0, 0, 0, 212, 213, 1, 0, 0, 0, 213, 214, 1, 0, 0, 0, 214, 215, 5, 9, 0, 0, 215, 216, 3, 108, 54, 0, 216, 25, 1, 0, 0, 0, 217, 218, 5, 18, 0, 0, 218, 219, 5, 97, 0, 0, 219, 220, 5, 5, 0, 0, 220, 221, 3, 84, 42, 0, 221, 222, 5, 19, 0, 0, 222, 27, 1, 0, 0, 0, 223, 224, 5, 20, 0, 0, 224, 225, 5, 97, 0, 0, 225, 227, 3, 30, 15, 0, 226, 228, 3, 38, 19, 0, 227, 226, 1, 0, 0, 0, 227, 228, 1, 0, 0, 0, 228, 230, 1, 0, 0, 0, 229, 231, 3, 36, 18, 0, 230, 229, 1, 0, 0, 0, 230, 231, 1, 0, 0, 0, 231, 232, 1, 0, 0, 0, 232, 233, 3, 34, 17, 0, 233, 29, 1, 0, 0, 0, 234, 235, 5, 21, 0, 0, 235, 238, 3, 32, 16, 0, 236, 237, 5, 22, 0, 0, 237, 239, 3, 32, 16, 0, 238, 236, 1, 0, 0, 0, 239, 240, 1, 0, 0, 0, 240, 238, 1, 0, 0, 0, 240, 241, 1, 0, 0, 0, 241, 242, 1, 0, 0, 0, 242, 243, 5, 23, 0, 0, 243, 31, 1, 0, 0, 0, 244, 245, 3, 110, 55, 0, 245, 247, 5, 97, 0, 0, 246, 248, 3, 40, 20, 0, 247, 246, 1, 0, 0, 0, 247, 248, 1, 0, 0, 0, 248, 33, 1, 0, 0, 0, 249, 253, 5, 2, 0, 0, 250, 252, 3, 42, 21, 0, 251, 250, 1, 0, 0, 0, 252, 255, 1, 0, 0, 0, 253, 251, 1, 0, 0, 0, 253, 254, 1, 0, 0, 0, 254, 256, 1, 0, 0, 0, 255, 253, 1, 0, 0, 0, 256, 257, 5, 3, 0, 0, 257, 35, 1, 0, 0, 0, 258, 259, 5, 24, 0, 0, 259, 260, 3, 106, 53, 0, 260, 261, 5, 25, 0, 0, 261, 37, 1, 0, 0, 0, 262, 263, 5, 26, 0, 0, 263, 264, 5, 97, 0, 0, 264, 39, 1, 0, 0, 0, 265, 266, 5, 7, 0, 0, 266, 267, 3, 22, 11, 0, 267, 41, 1, 0, 0, 0, 268, 269, 3, 60, 30, 0, 269, 270, 5, 27, 0, 0, 270, 272, 3, 60, 30, 0, 271, 273, 3, 46, 23, 0, 272, 271, 1, 0, 0, 0, 272, 273, 1, 0, 0, 0, 273, 274, 1, 0, 0, 0, 274, 275, 5, 19, 0, 0, 275, 280, 1, 0, 0, 0, 276, 277, 3, 44, 22, 0, 277, 278, 5, 19, 0, 0, 278, 280, 1, 0, 0, 0, 279, 268, 1, 0, 0, 0, 279, 276, 1, 0, 0, 0, 280, 43, 1, 0, 0, 0, 281, 284, 3, 48, 24, 0, 282, 283, 5, 27, 0, 0, 283, 285, 3, 52, 26, 0, 284, 282, 1, 0, 0, 0, 284, 285, 1, 0, 0, 0, 285, 287, 1, 0, 0, 0, 286, 288, 3, 72, 36, 0, 287, 286, 1, 0, 0, 0, 287, 288, 1, 0, 0, 0, 288, 290, 1, 0, 0, 0, 289, 291, 3, 46, 23, 0, 290, 289, 1, 0, 0, 0, 290, 291, 1, 0, 0, 0, 291, 45, 1, 0, 0, 0, 292, 293, 5, 101, 0, 0, 293, 47, 1, 0, 0, 0, 294, 299, 3, 50, 25, 0, 295, 296, 5, 22, 0, 0, 296, 298, 3, 50, 25, 0, 297, 295, 1, 0, 0, 0, 298, 301, 1, 0, 0, 0, 299, 297, 1, 0, 0, 0, 299, 300, 1, 0, 0, 0, 300, 49, 1, 0, 0, 0, 301, 299, 1, 0, 0, 0, 302, 304, 3, 60, 30, 0, 303, 305, 3, 40, 20, 0, 304, 303, 1, 0, 0, 0, 304, 305, 1, 0, 0, 0, 305, 307, 1, 0, 0, 0, 306, 308, 3, 56, 28, 0, 307, 306, 1, 0, 0, 0, 307, 308, 1, 0, 0, 0, 308, 310, 1, 0, 0, 0, 309, 311, 3, 62, 31, 0, 310, 309, 1, 0, 0, 0, 310, 311, 1, 0, 0, 0, 311, 313, 1, 0, 0, 0, 312, 314, 3, 102, 51, 0, 313, 312, 1, 0, 0, 0, 313, 314, 1, 0, 0, 0, 314, 316, 1, 0, 0, 0, 315, 317, 3, 64, 32, 0, 316, 315, 1, 0, 0, 0, 316, 317, 1, 0, 0, 0, 317, 319, 1, 0, 0, 0, 318, 320, 3, 66, 33, 0, 319, 318, 1, 0, 0, 0, 319, 320, 1, 0, 0, 0, 320, 322, 1, 0, 0, 0, 321, 323, 3, 68, 34, 0, 322, 321, 1, 0, 0, 0, 322, 323, 1, 0, 0, 0, 323, 325, 1, 0, 0, 0, 324, 326, 3, 70, 35, 0, 325, 324, 1, 0, 0, 0, 325, 326, 1, 0, 0, 0, 326, 51, 1, 0, 0, 0, 327, 332, 3, 54, 27, 0, 328, 329, 5, 22, 0, 0, 329, 331, 3, 54, 27, 0, 330, 328, 1, 0, 0, 0, 331, 334, 1, 0, 0, 0, 332, 330, 1, 0, 0, 0, 332, 333, 1, 0, 0, 0, 333, 53, 1, 0, 0, 0, 334, 332, 1, 0, 0, 0, 335, 338, 3, 60, 30, 0, 336, 337, 5, 5, 0, 0, 337, 339, 3, 76, 38, 0, 338, 336, 1, 0, 0, 0, 338, 339, 1, 0, 0, 0, 339, 341, 1, 0, 0, 0, 340, 342, 3, 64, 32, 0, 341, 340, 1, 0, 0, 0, 341, 342, 1, 0, 0, 0, 342, 344, 1, 0, 0, 0, 343, 345, 3, 104, 52, 0, 344, 343, 1, 0, 0, 0, 344, 345, 1, 0, 0, 0, 345, 360, 1, 0, 0, 0, 346, 347, 5, 21, 0, 0, 347, 348, 3, 84, 42, 0, 348, 350, 5, 23, 0, 0, 349, 351, 3, 64, 32, 0, 350, 349, 1, 0, 0, 0, 350, 351, 1, 0, 0, 0, 351, 353, 1, 0, 0, 0, 352, 354, 3, 104, 52, 0, 353, 352, 1, 0, 0, 0, 353, 354, 1, 0, 0, 0, 354, 360, 1, 0, 0, 0, 355, 357, 3, 78, 39, 0, 356, 358, 3, 64, 32, 0, 357, 356, 1, 0, 0, 0, 357, 358, 1, 0, 0, 0, 358, 360, 1, 0, 0, 0, 359, 335, 1, 0, 0, 0, 359, 346, 1, 0, 0, 0, 359, 355, 1, 0, 0, 0, 360, 55, 1, 0, 0, 0, 361, 362, 5, 96, 0, 0, 362, 363, 5, 28, 0, 0, 363, 364, 3, 58, 29, 0, 364, 57, 1, 0, 0, 0, 365, 366, 7, 3, 0, 0, 366, 59, 1, 0, 0, 0, 367, 372, 7, 4, 0, 0, 368, 369, 5, 39, 0, 0, 369, 371, 7, 4, 0, 0, 370, 368, 1, 0, 0, 0, 371, 374, 1, 0, 0, 0, 372, 370, 1, 0, 0, 0, 372, 373, 1, 0, 0, 0, 373, 61, 1, 0, 0, 0, 374, 372, 1, 0, 0, 0, 375, 376, 5, 40, 0, 0, 376, 377, 5, 21, 0, 0, 377, 378, 3, 84, 42, 0, 378, 379, 5, 23, 0, 0, 379, 383, 1, 0, 0, 0, 380, 381, 5, 40, 0, 0, 381, 383, 5, 101, 0, 0, 382, 375, 1, 0, 0, 0, 382, 380, 1, 0, 0, 0, 383, 63, 1, 0, 0, 0, 384, 385, 5, 9, 0, 0, 385, 386, 3, 22, 11, 0, 386, 65, 1, 0, 0, 0, 387, 388, 5, 34, 0, 0, 388, 389, 5, 21, 0, 0, 389, 390, 3, 84, 42, 0, 390, 391, 5, 23, 0, 0, 391, 67, 1, 0, 0, 0, 392, 393, 5, 35, 0, 0, 393, 394, 5, 21, 0, 0, 394, 395, 3, 84, 42, 0, 395, 396, 5, 23, 0, 0, 396, 69, 1, 0, 0, 0, 397, 398, 5, 41, 0, 0, 398, 399, 5, 21, 0, 0, 399, 400, 3, 84, 42, 0, 400, 401, 5, 23, 0, 0, 401, 71, 1, 0, 0, 0, 402, 415, 5, 42, 0, 0, 403, 408, 3, 78, 39, 0, 404, 405, 5, 22, 0, 0, 405, 407, 3, 78, 39, 0, 406, 404, 1, 0, 0, 0, 407, 410, 1, 0, 0, 0, 408, 406, 1, 0, 0, 0, 408, 409, 1, 0, 0, 0, 409, 412, 1, 0, 0, 0, 410, 408, 1, 0, 0, 0, 411, 413, 3, 34, 17, 0, 412, 411, 1, 0, 0, 0, 412, 413, 1, 0, 0, 0, 413, 416, 1, 0, 0, 0, 414, 416, 3, 34, 17, 0, 415, 403, 1, 0, 0, 0, 415, 414, 1, 0, 0, 0, 416, 73, 1, 0, 0, 0, 417, 418, 5, 30, 0, 0, 418, 419, 3, 20, 10, 0, 419, 75, 1, 0, 0, 0, 420, 428, 3, 112, 56, 0, 421, 428, 3, 60, 30, 0, 422, 428, 3, 78, 39, 0, 423, 424, 5, 21, 0, 0, 424, 425, 3, 84, 42, 0, 425, 426, 5, 23, 0, 0, 426, 428, 1, 0, 0, 0, 427, 420, 1, 0, 0, 0, 427, 421, 1, 0, 0, 0, 427, 422, 1, 0, 0, 0, 427, 423, 1, 0, 0, 0, 428, 77, 1, 0, 0, 0, 429, 430, 3, 22, 11, 0, 430, 432, 5, 21, 0, 0, 431, 433, 3, 80, 40, 0, 432, 431, 1, 0, 0, 0, 432, 433, 1, 0, 0, 0, 433, 434, 1, 0, 0, 0, 434, 435, 5, 23, 0, 0, 435, 79, 1, 0, 0, 0, 436, 441, 3, 82, 41, 0, 437, 438, 5, 22, 0, 0, 438, 440, 3, 82, 41, 0, 439, 437, 1, 0, 0, 0, 440, 443, 1, 0, 0, 0, 441, 439, 1, 0, 0, 0, 441, 442, 1, 0, 0, 0, 442, 81, 1, 0, 0, 0, 443, 441, 1, 0, 0, 0, 444, 447, 3, 112, 56, 0, 445, 447, 5, 97, 0, 0, 446, 444, 1, 0, 0, 0, 446, 445, 1, 0, 0, 0, 447, 83, 1, 0, 0, 0, 448, 449, 6, 42, -1, 0, 449, 453, 3, 86, 43, 0, 450, 451, 7, 5, 0, 0, 451, 453, 3, 84, 42, 11, 452, 448, 1, 0, 0, 0, 452, 450, 1, 0, 0, 0, 453, 494, 1, 0, 0, 0, 454, 455, 10, 10, 0, 0, 455, 456, 7, 6, 0, 0, 456, 493, 3, 84, 42, 11, 457, 458, 10, 9, 0, 0, 458, 459, 7, 7, 0, 0, 459, 493, 3, 84, 42, 10, 460, 461, 10, 7, 0, 0, 461, 462, 5, 49, 0, 0, 462, 493, 3, 84, 42, 8, 463, 464, 10, 6, 0, 0, 464, 465, 7, 8, 0, 0, 465, 493, 3, 84, 42, 7, 466, 467, 10, 5, 0, 0, 467, 468, 7, 9, 0, 0, 468, 493, 3, 84, 42, 6, 469, 470, 10, 4, 0, 0, 470, 471, 7, 10, 0, 0, 471, 493, 3, 84, 42, 5, 472, 473, 10, 3, 0, 0, 473, 474, 5, 57, 0, 0, 474, 493, 3, 84, 42, 4, 475, 476, 10, 2, 0, 0, 476, 477, 7, 11, 0, 0, 477, 493, 3, 84, 42, 3, 478, 479, 10, 1, 0, 0, 479, 480, 5, 60, 0, 0, 480, 493, 3, 84, 42, 2, 481, 482, 10, 13, 0, 0, 482, 483, 5, 39, 0, 0, 483, 493, 3, 88, 44, 0, 484, 485, 10, 12, 0, 0, 485, 486, 5, 43, 0, 0, 486, 487, 3, 84, 42, 0, 487, 488, 5, 44, 0, 0, 488, 493, 1, 0, 0, 0, 489, 490, 10, 8, 0, 0, 490, 491, 7, 12, 0, 0, 491, 493, 3, 98, 49, 0, 492, 454, 1, 0, 0, 0, 492, 457, 1, 0, 0, 0, 492, 460, 1, 0, 0, 0, 492, 463, 1, 0, 0, 0, 492, 466, 1, 0, 0, 0, 492, 469, 1, 0, 0, 0, 492, 472, 1, 0, 0, 0, 492, 475, 1, 0, 0, 0, 492, 478, 1, 0, 0, 0, 492, 481, 1, 0, 0, 0, 492, 484, 1, 0, 0, 0, 492, 489, 1, 0, 0, 0, 493, 496, 1, 0, 0, 0, 494, 492, 1, 0, 0, 0, 494, 495, 1, 0, 0, 0, 495, 85, 1, 0, 0, 0, 496, 494, 1, 0, 0, 0, 497, 505, 3, 88, 44, 0, 498, 505, 3, 112, 56, 0, 499, 505, 3, 90, 45, 0, 500, 501, 5, 21, 0, 0, 501, 502, 3, 84, 42, 0, 502, 503, 5, 23, 0, 0, 503, 505, 1, 0, 0, 0, 504, 497, 1, 0, 0, 0, 504, 498, 1, 0, 0, 0, 504, 499, 1, 0, 0, 0, 504, 500, 1, 0, 0, 0, 505, 87, 1, 0, 0, 0, 506, 512, 3, 92, 46, 0, 507, 512, 3, 22, 11, 0, 508, 512, 5, 61, 0, 0, 509, 512, 5, 62, 0, 0, 510, 512, 5, 63, 0, 0, 511, 506, 1, 0, 0, 0, 511, 507, 1, 0, 0, 0, 511, 508, 1, 0, 0, 0, 511, 509, 1, 0, 0, 0, 511, 510, 1, 0, 0, 0, 512, 89, 1, 0, 0, 0, 513, 516, 5, 64, 0, 0, 514, 517, 3, 22, 11, 0, 515, 517, 5, 100, 0, 0, 516, 514, 1, 0, 0, 0, 516, 515, 1, 0, 0, 0, 517, 91, 1, 0, 0, 0, 518, 519, 5, 15, 0, 0, 519, 528, 5, 21, 0, 0, 520, 525, 3, 94, 47, 0, 521, 522, 5, 22, 0, 0, 522, 524, 3, 94, 47, 0, 523, 521, 1, 0, 0, 0, 524, 527, 1, 0, 0, 0, 525, 523, 1, 0, 0, 0, 525, 526, 1, 0, 0, 0, 526, 529, 1, 0, 0, 0, 527, 525, 1, 0, 0, 0, 528, 520, 1, 0, 0, 0, 528, 529, 1, 0, 0, 0, 529, 530, 1, 0, 0, 0, 530, 539, 5, 23, 0, 0, 531, 532, 3, 60, 30, 0, 532, 534, 5, 21, 0, 0, 533, 535, 3, 96, 48, 0, 534, 533, 1, 0, 0, 0, 534, 535, 1, 0, 0, 0, 535, 536, 1, 0, 0, 0, 536, 537, 5, 23, 0, 0, 537, 539, 1, 0, 0, 0, 538, 518, 1, 0, 0, 0, 538, 531, 1, 0, 0, 0, 539, 93, 1, 0, 0, 0, 540, 542, 3, 84, 42, 0, 541, 543, 7, 13, 0, 0, 542, 541, 1, 0, 0, 0, 542, 543, 1, 0, 0, 0, 543, 95, 1, 0, 0, 0, 544, 549, 3, 84, 42, 0, 545, 546, 5, 22, 0, 0, 546, 548, 3, 84, 42, 0, 547, 545, 1, 0, 0, 0, 548, 551, 1, 0, 0, 0, 549, 547, 1, 0, 0, 0, 549, 550, 1, 0, 0, 0, 550, 97, 1, 0, 0, 0, 551, 549, 1, 0, 0, 0, 552, 553, 3, 60, 30, 0, 553, 99, 1, 0, 0, 0, 554, 555, 5, 97, 0, 0, 555, 101, 1, 0, 0, 0, 556, 557, 7, 14, 0, 0, 557, 103, 1, 0, 0, 0, 558, 559, 7, 15, 0, 0, 559, 105, 1, 0, 0, 0, 560, 561, 7, 16, 0, 0, 561, 107, 1, 0, 0, 0, 562, 563, 7, 17, 0, 0, 563, 109, 1, 0, 0, 0, 564, 565, 7, 18, 0, 0, 565, 111, 1, 0, 0, 0, 566, 577, 5, 89, 0, 0, 567, 577, 5, 90, 0, 0, 568, 577, 3, 114, 57, 0, 569, 577, 5, 94, 0, 0, 570, 577, 7, 19, 0, 0, 571, 577, 5, 91, 0, 0, 572, 577, 5, 92, 0, 0, 573, 577, 5, 93, 0, 0, 574, 577, 5, 100, 0, 0, 575, 577, 5, 101, 0, 0, 576, 566, 1, 0, 0, 0, 576, 567, 1, 0, 0, 0, 576, 568, 1, 0, 0, 0, 576, 569, 1, 0, 0, 0, 576, 570, 1, 0, 0, 0, 576, 571, 1, 0, 0, 0, 576, 572, 1, 0, 0, 0, 576, 573, 1, 0, 0, 0, 576, 574, 1, 0, 0, 0, 576, 575, 1, 0, 0, 0, 577, 113, 1, 0, 0, 0, 578, 579, 7, 19, 0, 0, 579, 585, 7, 20, 0, 0, 580, 581, 7, 19, 0, 0, 581, 585, 7, 21, 0, 0, 582, 583, 7, 19, 0, 0, 583, 585, 5, 100, 0, 0, 584, 578, 1, 0, 0, 0, 584, 580, 1, 0, 0, 0, 584, 582, 1, 0, 0, 0, 585, 115, 1, 0, 0, 0, 61, 119, 125, 129, 134, 140, 146, 152, 162, 167, 200, 212, 227, 230, 240, 247, 253, 272, 279, 284, 287, 290, 299, 304, 307, 310, 313, 316, 319, 322, 325, 332, 338, 341, 344, 350, 353, 357, 359, 372, 382, 408, 412, 415, 427, 432, 441, 446, 452, 492, 494, 504, 511, 516, 525, 528, 534, 538, 542, 549, 576, 584] \ No newline at end of file +[4, 1, 106, 589, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 1, 0, 5, 0, 118, 8, 0, 10, 0, 12, 0, 121, 9, 0, 1, 0, 5, 0, 124, 8, 0, 10, 0, 12, 0, 127, 9, 0, 1, 0, 3, 0, 130, 8, 0, 1, 0, 5, 0, 133, 8, 0, 10, 0, 12, 0, 136, 9, 0, 1, 0, 5, 0, 139, 8, 0, 10, 0, 12, 0, 142, 9, 0, 1, 0, 5, 0, 145, 8, 0, 10, 0, 12, 0, 148, 9, 0, 1, 0, 4, 0, 151, 8, 0, 11, 0, 12, 0, 152, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 161, 8, 1, 11, 1, 12, 1, 162, 1, 1, 4, 1, 166, 8, 1, 11, 1, 12, 1, 167, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 196, 8, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 203, 8, 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 3, 12, 215, 8, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 3, 14, 230, 8, 14, 1, 14, 3, 14, 233, 8, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 4, 15, 241, 8, 15, 11, 15, 12, 15, 242, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 3, 16, 250, 8, 16, 1, 17, 1, 17, 5, 17, 254, 8, 17, 10, 17, 12, 17, 257, 9, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 3, 21, 275, 8, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 3, 21, 282, 8, 21, 1, 22, 1, 22, 1, 22, 3, 22, 287, 8, 22, 1, 22, 3, 22, 290, 8, 22, 1, 22, 3, 22, 293, 8, 22, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 5, 24, 300, 8, 24, 10, 24, 12, 24, 303, 9, 24, 1, 25, 1, 25, 3, 25, 307, 8, 25, 1, 25, 3, 25, 310, 8, 25, 1, 25, 3, 25, 313, 8, 25, 1, 25, 3, 25, 316, 8, 25, 1, 25, 3, 25, 319, 8, 25, 1, 25, 3, 25, 322, 8, 25, 1, 25, 3, 25, 325, 8, 25, 1, 25, 3, 25, 328, 8, 25, 1, 26, 1, 26, 1, 26, 5, 26, 333, 8, 26, 10, 26, 12, 26, 336, 9, 26, 1, 27, 1, 27, 1, 27, 3, 27, 341, 8, 27, 1, 27, 3, 27, 344, 8, 27, 1, 27, 3, 27, 347, 8, 27, 1, 27, 1, 27, 1, 27, 1, 27, 3, 27, 353, 8, 27, 1, 27, 3, 27, 356, 8, 27, 1, 27, 1, 27, 3, 27, 360, 8, 27, 3, 27, 362, 8, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 5, 30, 373, 8, 30, 10, 30, 12, 30, 376, 9, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 3, 31, 385, 8, 31, 1, 32, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 5, 36, 409, 8, 36, 10, 36, 12, 36, 412, 9, 36, 1, 36, 3, 36, 415, 8, 36, 1, 36, 3, 36, 418, 8, 36, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 3, 38, 430, 8, 38, 1, 39, 1, 39, 1, 39, 3, 39, 435, 8, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 5, 40, 442, 8, 40, 10, 40, 12, 40, 445, 9, 40, 1, 41, 1, 41, 3, 41, 449, 8, 41, 1, 42, 1, 42, 1, 42, 1, 42, 3, 42, 455, 8, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 5, 42, 495, 8, 42, 10, 42, 12, 42, 498, 9, 42, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 3, 43, 507, 8, 43, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 3, 44, 514, 8, 44, 1, 45, 1, 45, 1, 45, 3, 45, 519, 8, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 5, 46, 526, 8, 46, 10, 46, 12, 46, 529, 9, 46, 3, 46, 531, 8, 46, 1, 46, 1, 46, 1, 46, 1, 46, 3, 46, 537, 8, 46, 1, 46, 1, 46, 3, 46, 541, 8, 46, 1, 47, 1, 47, 3, 47, 545, 8, 47, 1, 48, 1, 48, 1, 48, 5, 48, 550, 8, 48, 10, 48, 12, 48, 553, 9, 48, 1, 49, 1, 49, 1, 50, 1, 50, 1, 51, 1, 51, 1, 52, 1, 52, 1, 53, 1, 53, 1, 54, 1, 54, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 3, 56, 579, 8, 56, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 3, 57, 587, 8, 57, 1, 57, 5, 119, 125, 134, 140, 146, 1, 84, 58, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 0, 22, 2, 0, 97, 97, 100, 101, 1, 0, 100, 101, 2, 0, 9, 15, 97, 99, 2, 0, 29, 29, 96, 96, 7, 0, 4, 4, 8, 10, 12, 18, 20, 20, 26, 26, 30, 38, 97, 98, 2, 0, 6, 6, 45, 45, 3, 0, 29, 29, 36, 36, 46, 47, 3, 0, 6, 6, 45, 45, 48, 48, 1, 0, 50, 53, 2, 0, 5, 5, 54, 56, 1, 0, 10, 11, 1, 0, 58, 59, 2, 0, 9, 9, 12, 12, 1, 0, 13, 14, 2, 0, 37, 38, 65, 67, 2, 0, 37, 38, 68, 69, 2, 0, 33, 33, 70, 70, 2, 0, 31, 32, 71, 72, 1, 0, 31, 32, 1, 0, 95, 96, 1, 0, 73, 80, 1, 0, 81, 88, 620, 0, 119, 1, 0, 0, 0, 2, 156, 1, 0, 0, 0, 4, 171, 1, 0, 0, 0, 6, 176, 1, 0, 0, 0, 8, 180, 1, 0, 0, 0, 10, 184, 1, 0, 0, 0, 12, 188, 1, 0, 0, 0, 14, 190, 1, 0, 0, 0, 16, 197, 1, 0, 0, 0, 18, 204, 1, 0, 0, 0, 20, 206, 1, 0, 0, 0, 22, 208, 1, 0, 0, 0, 24, 210, 1, 0, 0, 0, 26, 219, 1, 0, 0, 0, 28, 225, 1, 0, 0, 0, 30, 236, 1, 0, 0, 0, 32, 246, 1, 0, 0, 0, 34, 251, 1, 0, 0, 0, 36, 260, 1, 0, 0, 0, 38, 264, 1, 0, 0, 0, 40, 267, 1, 0, 0, 0, 42, 281, 1, 0, 0, 0, 44, 283, 1, 0, 0, 0, 46, 294, 1, 0, 0, 0, 48, 296, 1, 0, 0, 0, 50, 304, 1, 0, 0, 0, 52, 329, 1, 0, 0, 0, 54, 361, 1, 0, 0, 0, 56, 363, 1, 0, 0, 0, 58, 367, 1, 0, 0, 0, 60, 369, 1, 0, 0, 0, 62, 384, 1, 0, 0, 0, 64, 386, 1, 0, 0, 0, 66, 389, 1, 0, 0, 0, 68, 394, 1, 0, 0, 0, 70, 399, 1, 0, 0, 0, 72, 404, 1, 0, 0, 0, 74, 419, 1, 0, 0, 0, 76, 429, 1, 0, 0, 0, 78, 431, 1, 0, 0, 0, 80, 438, 1, 0, 0, 0, 82, 448, 1, 0, 0, 0, 84, 454, 1, 0, 0, 0, 86, 506, 1, 0, 0, 0, 88, 513, 1, 0, 0, 0, 90, 515, 1, 0, 0, 0, 92, 540, 1, 0, 0, 0, 94, 542, 1, 0, 0, 0, 96, 546, 1, 0, 0, 0, 98, 554, 1, 0, 0, 0, 100, 556, 1, 0, 0, 0, 102, 558, 1, 0, 0, 0, 104, 560, 1, 0, 0, 0, 106, 562, 1, 0, 0, 0, 108, 564, 1, 0, 0, 0, 110, 566, 1, 0, 0, 0, 112, 578, 1, 0, 0, 0, 114, 586, 1, 0, 0, 0, 116, 118, 3, 16, 8, 0, 117, 116, 1, 0, 0, 0, 118, 121, 1, 0, 0, 0, 119, 120, 1, 0, 0, 0, 119, 117, 1, 0, 0, 0, 120, 125, 1, 0, 0, 0, 121, 119, 1, 0, 0, 0, 122, 124, 3, 2, 1, 0, 123, 122, 1, 0, 0, 0, 124, 127, 1, 0, 0, 0, 125, 126, 1, 0, 0, 0, 125, 123, 1, 0, 0, 0, 126, 129, 1, 0, 0, 0, 127, 125, 1, 0, 0, 0, 128, 130, 3, 14, 7, 0, 129, 128, 1, 0, 0, 0, 129, 130, 1, 0, 0, 0, 130, 134, 1, 0, 0, 0, 131, 133, 3, 24, 12, 0, 132, 131, 1, 0, 0, 0, 133, 136, 1, 0, 0, 0, 134, 135, 1, 0, 0, 0, 134, 132, 1, 0, 0, 0, 135, 140, 1, 0, 0, 0, 136, 134, 1, 0, 0, 0, 137, 139, 3, 74, 37, 0, 138, 137, 1, 0, 0, 0, 139, 142, 1, 0, 0, 0, 140, 141, 1, 0, 0, 0, 140, 138, 1, 0, 0, 0, 141, 146, 1, 0, 0, 0, 142, 140, 1, 0, 0, 0, 143, 145, 3, 26, 13, 0, 144, 143, 1, 0, 0, 0, 145, 148, 1, 0, 0, 0, 146, 147, 1, 0, 0, 0, 146, 144, 1, 0, 0, 0, 147, 150, 1, 0, 0, 0, 148, 146, 1, 0, 0, 0, 149, 151, 3, 28, 14, 0, 150, 149, 1, 0, 0, 0, 151, 152, 1, 0, 0, 0, 152, 150, 1, 0, 0, 0, 152, 153, 1, 0, 0, 0, 153, 154, 1, 0, 0, 0, 154, 155, 5, 0, 0, 1, 155, 1, 1, 0, 0, 0, 156, 157, 5, 1, 0, 0, 157, 158, 3, 20, 10, 0, 158, 160, 5, 2, 0, 0, 159, 161, 3, 4, 2, 0, 160, 159, 1, 0, 0, 0, 161, 162, 1, 0, 0, 0, 162, 160, 1, 0, 0, 0, 162, 163, 1, 0, 0, 0, 163, 165, 1, 0, 0, 0, 164, 166, 3, 6, 3, 0, 165, 164, 1, 0, 0, 0, 166, 167, 1, 0, 0, 0, 167, 165, 1, 0, 0, 0, 167, 168, 1, 0, 0, 0, 168, 169, 1, 0, 0, 0, 169, 170, 5, 3, 0, 0, 170, 3, 1, 0, 0, 0, 171, 172, 5, 4, 0, 0, 172, 173, 5, 97, 0, 0, 173, 174, 5, 5, 0, 0, 174, 175, 3, 20, 10, 0, 175, 5, 1, 0, 0, 0, 176, 177, 3, 8, 4, 0, 177, 178, 5, 6, 0, 0, 178, 179, 3, 10, 5, 0, 179, 7, 1, 0, 0, 0, 180, 181, 5, 97, 0, 0, 181, 182, 5, 7, 0, 0, 182, 183, 3, 12, 6, 0, 183, 9, 1, 0, 0, 0, 184, 185, 5, 97, 0, 0, 185, 186, 5, 7, 0, 0, 186, 187, 3, 12, 6, 0, 187, 11, 1, 0, 0, 0, 188, 189, 7, 0, 0, 0, 189, 13, 1, 0, 0, 0, 190, 191, 5, 8, 0, 0, 191, 192, 3, 20, 10, 0, 192, 195, 5, 5, 0, 0, 193, 196, 3, 22, 11, 0, 194, 196, 5, 101, 0, 0, 195, 193, 1, 0, 0, 0, 195, 194, 1, 0, 0, 0, 196, 15, 1, 0, 0, 0, 197, 198, 5, 105, 0, 0, 198, 199, 3, 60, 30, 0, 199, 202, 5, 5, 0, 0, 200, 203, 3, 112, 56, 0, 201, 203, 3, 18, 9, 0, 202, 200, 1, 0, 0, 0, 202, 201, 1, 0, 0, 0, 202, 203, 1, 0, 0, 0, 203, 17, 1, 0, 0, 0, 204, 205, 5, 102, 0, 0, 205, 19, 1, 0, 0, 0, 206, 207, 7, 1, 0, 0, 207, 21, 1, 0, 0, 0, 208, 209, 7, 2, 0, 0, 209, 23, 1, 0, 0, 0, 210, 211, 5, 16, 0, 0, 211, 214, 3, 20, 10, 0, 212, 213, 5, 17, 0, 0, 213, 215, 3, 22, 11, 0, 214, 212, 1, 0, 0, 0, 214, 215, 1, 0, 0, 0, 215, 216, 1, 0, 0, 0, 216, 217, 5, 9, 0, 0, 217, 218, 3, 108, 54, 0, 218, 25, 1, 0, 0, 0, 219, 220, 5, 18, 0, 0, 220, 221, 5, 97, 0, 0, 221, 222, 5, 5, 0, 0, 222, 223, 3, 84, 42, 0, 223, 224, 5, 19, 0, 0, 224, 27, 1, 0, 0, 0, 225, 226, 5, 20, 0, 0, 226, 227, 5, 97, 0, 0, 227, 229, 3, 30, 15, 0, 228, 230, 3, 38, 19, 0, 229, 228, 1, 0, 0, 0, 229, 230, 1, 0, 0, 0, 230, 232, 1, 0, 0, 0, 231, 233, 3, 36, 18, 0, 232, 231, 1, 0, 0, 0, 232, 233, 1, 0, 0, 0, 233, 234, 1, 0, 0, 0, 234, 235, 3, 34, 17, 0, 235, 29, 1, 0, 0, 0, 236, 237, 5, 21, 0, 0, 237, 240, 3, 32, 16, 0, 238, 239, 5, 22, 0, 0, 239, 241, 3, 32, 16, 0, 240, 238, 1, 0, 0, 0, 241, 242, 1, 0, 0, 0, 242, 240, 1, 0, 0, 0, 242, 243, 1, 0, 0, 0, 243, 244, 1, 0, 0, 0, 244, 245, 5, 23, 0, 0, 245, 31, 1, 0, 0, 0, 246, 247, 3, 110, 55, 0, 247, 249, 5, 97, 0, 0, 248, 250, 3, 40, 20, 0, 249, 248, 1, 0, 0, 0, 249, 250, 1, 0, 0, 0, 250, 33, 1, 0, 0, 0, 251, 255, 5, 2, 0, 0, 252, 254, 3, 42, 21, 0, 253, 252, 1, 0, 0, 0, 254, 257, 1, 0, 0, 0, 255, 253, 1, 0, 0, 0, 255, 256, 1, 0, 0, 0, 256, 258, 1, 0, 0, 0, 257, 255, 1, 0, 0, 0, 258, 259, 5, 3, 0, 0, 259, 35, 1, 0, 0, 0, 260, 261, 5, 24, 0, 0, 261, 262, 3, 106, 53, 0, 262, 263, 5, 25, 0, 0, 263, 37, 1, 0, 0, 0, 264, 265, 5, 26, 0, 0, 265, 266, 5, 97, 0, 0, 266, 39, 1, 0, 0, 0, 267, 268, 5, 7, 0, 0, 268, 269, 3, 22, 11, 0, 269, 41, 1, 0, 0, 0, 270, 271, 3, 60, 30, 0, 271, 272, 5, 27, 0, 0, 272, 274, 3, 60, 30, 0, 273, 275, 3, 46, 23, 0, 274, 273, 1, 0, 0, 0, 274, 275, 1, 0, 0, 0, 275, 276, 1, 0, 0, 0, 276, 277, 5, 19, 0, 0, 277, 282, 1, 0, 0, 0, 278, 279, 3, 44, 22, 0, 279, 280, 5, 19, 0, 0, 280, 282, 1, 0, 0, 0, 281, 270, 1, 0, 0, 0, 281, 278, 1, 0, 0, 0, 282, 43, 1, 0, 0, 0, 283, 286, 3, 48, 24, 0, 284, 285, 5, 27, 0, 0, 285, 287, 3, 52, 26, 0, 286, 284, 1, 0, 0, 0, 286, 287, 1, 0, 0, 0, 287, 289, 1, 0, 0, 0, 288, 290, 3, 72, 36, 0, 289, 288, 1, 0, 0, 0, 289, 290, 1, 0, 0, 0, 290, 292, 1, 0, 0, 0, 291, 293, 3, 46, 23, 0, 292, 291, 1, 0, 0, 0, 292, 293, 1, 0, 0, 0, 293, 45, 1, 0, 0, 0, 294, 295, 5, 101, 0, 0, 295, 47, 1, 0, 0, 0, 296, 301, 3, 50, 25, 0, 297, 298, 5, 22, 0, 0, 298, 300, 3, 50, 25, 0, 299, 297, 1, 0, 0, 0, 300, 303, 1, 0, 0, 0, 301, 299, 1, 0, 0, 0, 301, 302, 1, 0, 0, 0, 302, 49, 1, 0, 0, 0, 303, 301, 1, 0, 0, 0, 304, 306, 3, 60, 30, 0, 305, 307, 3, 40, 20, 0, 306, 305, 1, 0, 0, 0, 306, 307, 1, 0, 0, 0, 307, 309, 1, 0, 0, 0, 308, 310, 3, 56, 28, 0, 309, 308, 1, 0, 0, 0, 309, 310, 1, 0, 0, 0, 310, 312, 1, 0, 0, 0, 311, 313, 3, 62, 31, 0, 312, 311, 1, 0, 0, 0, 312, 313, 1, 0, 0, 0, 313, 315, 1, 0, 0, 0, 314, 316, 3, 102, 51, 0, 315, 314, 1, 0, 0, 0, 315, 316, 1, 0, 0, 0, 316, 318, 1, 0, 0, 0, 317, 319, 3, 64, 32, 0, 318, 317, 1, 0, 0, 0, 318, 319, 1, 0, 0, 0, 319, 321, 1, 0, 0, 0, 320, 322, 3, 66, 33, 0, 321, 320, 1, 0, 0, 0, 321, 322, 1, 0, 0, 0, 322, 324, 1, 0, 0, 0, 323, 325, 3, 68, 34, 0, 324, 323, 1, 0, 0, 0, 324, 325, 1, 0, 0, 0, 325, 327, 1, 0, 0, 0, 326, 328, 3, 70, 35, 0, 327, 326, 1, 0, 0, 0, 327, 328, 1, 0, 0, 0, 328, 51, 1, 0, 0, 0, 329, 334, 3, 54, 27, 0, 330, 331, 5, 22, 0, 0, 331, 333, 3, 54, 27, 0, 332, 330, 1, 0, 0, 0, 333, 336, 1, 0, 0, 0, 334, 332, 1, 0, 0, 0, 334, 335, 1, 0, 0, 0, 335, 53, 1, 0, 0, 0, 336, 334, 1, 0, 0, 0, 337, 340, 3, 60, 30, 0, 338, 339, 5, 5, 0, 0, 339, 341, 3, 76, 38, 0, 340, 338, 1, 0, 0, 0, 340, 341, 1, 0, 0, 0, 341, 343, 1, 0, 0, 0, 342, 344, 3, 64, 32, 0, 343, 342, 1, 0, 0, 0, 343, 344, 1, 0, 0, 0, 344, 346, 1, 0, 0, 0, 345, 347, 3, 104, 52, 0, 346, 345, 1, 0, 0, 0, 346, 347, 1, 0, 0, 0, 347, 362, 1, 0, 0, 0, 348, 349, 5, 21, 0, 0, 349, 350, 3, 84, 42, 0, 350, 352, 5, 23, 0, 0, 351, 353, 3, 64, 32, 0, 352, 351, 1, 0, 0, 0, 352, 353, 1, 0, 0, 0, 353, 355, 1, 0, 0, 0, 354, 356, 3, 104, 52, 0, 355, 354, 1, 0, 0, 0, 355, 356, 1, 0, 0, 0, 356, 362, 1, 0, 0, 0, 357, 359, 3, 78, 39, 0, 358, 360, 3, 64, 32, 0, 359, 358, 1, 0, 0, 0, 359, 360, 1, 0, 0, 0, 360, 362, 1, 0, 0, 0, 361, 337, 1, 0, 0, 0, 361, 348, 1, 0, 0, 0, 361, 357, 1, 0, 0, 0, 362, 55, 1, 0, 0, 0, 363, 364, 5, 96, 0, 0, 364, 365, 5, 28, 0, 0, 365, 366, 3, 58, 29, 0, 366, 57, 1, 0, 0, 0, 367, 368, 7, 3, 0, 0, 368, 59, 1, 0, 0, 0, 369, 374, 7, 4, 0, 0, 370, 371, 5, 39, 0, 0, 371, 373, 7, 4, 0, 0, 372, 370, 1, 0, 0, 0, 373, 376, 1, 0, 0, 0, 374, 372, 1, 0, 0, 0, 374, 375, 1, 0, 0, 0, 375, 61, 1, 0, 0, 0, 376, 374, 1, 0, 0, 0, 377, 378, 5, 40, 0, 0, 378, 379, 5, 21, 0, 0, 379, 380, 3, 84, 42, 0, 380, 381, 5, 23, 0, 0, 381, 385, 1, 0, 0, 0, 382, 383, 5, 40, 0, 0, 383, 385, 5, 101, 0, 0, 384, 377, 1, 0, 0, 0, 384, 382, 1, 0, 0, 0, 385, 63, 1, 0, 0, 0, 386, 387, 5, 9, 0, 0, 387, 388, 3, 22, 11, 0, 388, 65, 1, 0, 0, 0, 389, 390, 5, 34, 0, 0, 390, 391, 5, 21, 0, 0, 391, 392, 3, 84, 42, 0, 392, 393, 5, 23, 0, 0, 393, 67, 1, 0, 0, 0, 394, 395, 5, 35, 0, 0, 395, 396, 5, 21, 0, 0, 396, 397, 3, 84, 42, 0, 397, 398, 5, 23, 0, 0, 398, 69, 1, 0, 0, 0, 399, 400, 5, 41, 0, 0, 400, 401, 5, 21, 0, 0, 401, 402, 3, 84, 42, 0, 402, 403, 5, 23, 0, 0, 403, 71, 1, 0, 0, 0, 404, 417, 5, 42, 0, 0, 405, 410, 3, 78, 39, 0, 406, 407, 5, 22, 0, 0, 407, 409, 3, 78, 39, 0, 408, 406, 1, 0, 0, 0, 409, 412, 1, 0, 0, 0, 410, 408, 1, 0, 0, 0, 410, 411, 1, 0, 0, 0, 411, 414, 1, 0, 0, 0, 412, 410, 1, 0, 0, 0, 413, 415, 3, 34, 17, 0, 414, 413, 1, 0, 0, 0, 414, 415, 1, 0, 0, 0, 415, 418, 1, 0, 0, 0, 416, 418, 3, 34, 17, 0, 417, 405, 1, 0, 0, 0, 417, 416, 1, 0, 0, 0, 418, 73, 1, 0, 0, 0, 419, 420, 5, 30, 0, 0, 420, 421, 3, 20, 10, 0, 421, 75, 1, 0, 0, 0, 422, 430, 3, 112, 56, 0, 423, 430, 3, 60, 30, 0, 424, 430, 3, 78, 39, 0, 425, 426, 5, 21, 0, 0, 426, 427, 3, 84, 42, 0, 427, 428, 5, 23, 0, 0, 428, 430, 1, 0, 0, 0, 429, 422, 1, 0, 0, 0, 429, 423, 1, 0, 0, 0, 429, 424, 1, 0, 0, 0, 429, 425, 1, 0, 0, 0, 430, 77, 1, 0, 0, 0, 431, 432, 3, 22, 11, 0, 432, 434, 5, 21, 0, 0, 433, 435, 3, 80, 40, 0, 434, 433, 1, 0, 0, 0, 434, 435, 1, 0, 0, 0, 435, 436, 1, 0, 0, 0, 436, 437, 5, 23, 0, 0, 437, 79, 1, 0, 0, 0, 438, 443, 3, 82, 41, 0, 439, 440, 5, 22, 0, 0, 440, 442, 3, 82, 41, 0, 441, 439, 1, 0, 0, 0, 442, 445, 1, 0, 0, 0, 443, 441, 1, 0, 0, 0, 443, 444, 1, 0, 0, 0, 444, 81, 1, 0, 0, 0, 445, 443, 1, 0, 0, 0, 446, 449, 3, 112, 56, 0, 447, 449, 5, 97, 0, 0, 448, 446, 1, 0, 0, 0, 448, 447, 1, 0, 0, 0, 449, 83, 1, 0, 0, 0, 450, 451, 6, 42, -1, 0, 451, 455, 3, 86, 43, 0, 452, 453, 7, 5, 0, 0, 453, 455, 3, 84, 42, 11, 454, 450, 1, 0, 0, 0, 454, 452, 1, 0, 0, 0, 455, 496, 1, 0, 0, 0, 456, 457, 10, 10, 0, 0, 457, 458, 7, 6, 0, 0, 458, 495, 3, 84, 42, 11, 459, 460, 10, 9, 0, 0, 460, 461, 7, 7, 0, 0, 461, 495, 3, 84, 42, 10, 462, 463, 10, 7, 0, 0, 463, 464, 5, 49, 0, 0, 464, 495, 3, 84, 42, 8, 465, 466, 10, 6, 0, 0, 466, 467, 7, 8, 0, 0, 467, 495, 3, 84, 42, 7, 468, 469, 10, 5, 0, 0, 469, 470, 7, 9, 0, 0, 470, 495, 3, 84, 42, 6, 471, 472, 10, 4, 0, 0, 472, 473, 7, 10, 0, 0, 473, 495, 3, 84, 42, 5, 474, 475, 10, 3, 0, 0, 475, 476, 5, 57, 0, 0, 476, 495, 3, 84, 42, 4, 477, 478, 10, 2, 0, 0, 478, 479, 7, 11, 0, 0, 479, 495, 3, 84, 42, 3, 480, 481, 10, 1, 0, 0, 481, 482, 5, 60, 0, 0, 482, 495, 3, 84, 42, 2, 483, 484, 10, 13, 0, 0, 484, 485, 5, 39, 0, 0, 485, 495, 3, 88, 44, 0, 486, 487, 10, 12, 0, 0, 487, 488, 5, 43, 0, 0, 488, 489, 3, 84, 42, 0, 489, 490, 5, 44, 0, 0, 490, 495, 1, 0, 0, 0, 491, 492, 10, 8, 0, 0, 492, 493, 7, 12, 0, 0, 493, 495, 3, 98, 49, 0, 494, 456, 1, 0, 0, 0, 494, 459, 1, 0, 0, 0, 494, 462, 1, 0, 0, 0, 494, 465, 1, 0, 0, 0, 494, 468, 1, 0, 0, 0, 494, 471, 1, 0, 0, 0, 494, 474, 1, 0, 0, 0, 494, 477, 1, 0, 0, 0, 494, 480, 1, 0, 0, 0, 494, 483, 1, 0, 0, 0, 494, 486, 1, 0, 0, 0, 494, 491, 1, 0, 0, 0, 495, 498, 1, 0, 0, 0, 496, 494, 1, 0, 0, 0, 496, 497, 1, 0, 0, 0, 497, 85, 1, 0, 0, 0, 498, 496, 1, 0, 0, 0, 499, 507, 3, 88, 44, 0, 500, 507, 3, 112, 56, 0, 501, 507, 3, 90, 45, 0, 502, 503, 5, 21, 0, 0, 503, 504, 3, 84, 42, 0, 504, 505, 5, 23, 0, 0, 505, 507, 1, 0, 0, 0, 506, 499, 1, 0, 0, 0, 506, 500, 1, 0, 0, 0, 506, 501, 1, 0, 0, 0, 506, 502, 1, 0, 0, 0, 507, 87, 1, 0, 0, 0, 508, 514, 3, 92, 46, 0, 509, 514, 3, 22, 11, 0, 510, 514, 5, 61, 0, 0, 511, 514, 5, 62, 0, 0, 512, 514, 5, 63, 0, 0, 513, 508, 1, 0, 0, 0, 513, 509, 1, 0, 0, 0, 513, 510, 1, 0, 0, 0, 513, 511, 1, 0, 0, 0, 513, 512, 1, 0, 0, 0, 514, 89, 1, 0, 0, 0, 515, 518, 5, 64, 0, 0, 516, 519, 3, 22, 11, 0, 517, 519, 5, 100, 0, 0, 518, 516, 1, 0, 0, 0, 518, 517, 1, 0, 0, 0, 519, 91, 1, 0, 0, 0, 520, 521, 5, 15, 0, 0, 521, 530, 5, 21, 0, 0, 522, 527, 3, 94, 47, 0, 523, 524, 5, 22, 0, 0, 524, 526, 3, 94, 47, 0, 525, 523, 1, 0, 0, 0, 526, 529, 1, 0, 0, 0, 527, 525, 1, 0, 0, 0, 527, 528, 1, 0, 0, 0, 528, 531, 1, 0, 0, 0, 529, 527, 1, 0, 0, 0, 530, 522, 1, 0, 0, 0, 530, 531, 1, 0, 0, 0, 531, 532, 1, 0, 0, 0, 532, 541, 5, 23, 0, 0, 533, 534, 3, 60, 30, 0, 534, 536, 5, 21, 0, 0, 535, 537, 3, 96, 48, 0, 536, 535, 1, 0, 0, 0, 536, 537, 1, 0, 0, 0, 537, 538, 1, 0, 0, 0, 538, 539, 5, 23, 0, 0, 539, 541, 1, 0, 0, 0, 540, 520, 1, 0, 0, 0, 540, 533, 1, 0, 0, 0, 541, 93, 1, 0, 0, 0, 542, 544, 3, 84, 42, 0, 543, 545, 7, 13, 0, 0, 544, 543, 1, 0, 0, 0, 544, 545, 1, 0, 0, 0, 545, 95, 1, 0, 0, 0, 546, 551, 3, 84, 42, 0, 547, 548, 5, 22, 0, 0, 548, 550, 3, 84, 42, 0, 549, 547, 1, 0, 0, 0, 550, 553, 1, 0, 0, 0, 551, 549, 1, 0, 0, 0, 551, 552, 1, 0, 0, 0, 552, 97, 1, 0, 0, 0, 553, 551, 1, 0, 0, 0, 554, 555, 3, 60, 30, 0, 555, 99, 1, 0, 0, 0, 556, 557, 5, 97, 0, 0, 557, 101, 1, 0, 0, 0, 558, 559, 7, 14, 0, 0, 559, 103, 1, 0, 0, 0, 560, 561, 7, 15, 0, 0, 561, 105, 1, 0, 0, 0, 562, 563, 7, 16, 0, 0, 563, 107, 1, 0, 0, 0, 564, 565, 7, 17, 0, 0, 565, 109, 1, 0, 0, 0, 566, 567, 7, 18, 0, 0, 567, 111, 1, 0, 0, 0, 568, 579, 5, 89, 0, 0, 569, 579, 5, 90, 0, 0, 570, 579, 3, 114, 57, 0, 571, 579, 5, 94, 0, 0, 572, 579, 7, 19, 0, 0, 573, 579, 5, 91, 0, 0, 574, 579, 5, 92, 0, 0, 575, 579, 5, 93, 0, 0, 576, 579, 5, 100, 0, 0, 577, 579, 5, 101, 0, 0, 578, 568, 1, 0, 0, 0, 578, 569, 1, 0, 0, 0, 578, 570, 1, 0, 0, 0, 578, 571, 1, 0, 0, 0, 578, 572, 1, 0, 0, 0, 578, 573, 1, 0, 0, 0, 578, 574, 1, 0, 0, 0, 578, 575, 1, 0, 0, 0, 578, 576, 1, 0, 0, 0, 578, 577, 1, 0, 0, 0, 579, 113, 1, 0, 0, 0, 580, 581, 7, 19, 0, 0, 581, 587, 7, 20, 0, 0, 582, 583, 7, 19, 0, 0, 583, 587, 7, 21, 0, 0, 584, 585, 7, 19, 0, 0, 585, 587, 5, 100, 0, 0, 586, 580, 1, 0, 0, 0, 586, 582, 1, 0, 0, 0, 586, 584, 1, 0, 0, 0, 587, 115, 1, 0, 0, 0, 62, 119, 125, 129, 134, 140, 146, 152, 162, 167, 195, 202, 214, 229, 232, 242, 249, 255, 274, 281, 286, 289, 292, 301, 306, 309, 312, 315, 318, 321, 324, 327, 334, 340, 343, 346, 352, 355, 359, 361, 374, 384, 410, 414, 417, 429, 434, 443, 448, 454, 494, 496, 506, 513, 518, 527, 530, 536, 540, 544, 551, 578, 586] \ No newline at end of file diff --git a/fml-parser/FmlMappingParser.ts b/fml-parser/FmlMappingParser.ts index c9623b26..eeb710fe 100644 --- a/fml-parser/FmlMappingParser.ts +++ b/fml-parser/FmlMappingParser.ts @@ -684,8 +684,33 @@ export default class FmlMappingParser extends Parser { this.url(); this.state = 192; this.match(FmlMappingParser.T__4); - this.state = 193; - this.identifier(); + this.state = 195; + this._errHandler.sync(this); + switch (this._input.LA(1)) { + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 97: + case 98: + case 99: + { + this.state = 193; + this.identifier(); + } + break; + case 101: + { + this.state = 194; + this.match(FmlMappingParser.DOUBLE_QUOTED_STRING); + } + break; + default: + throw new NoViableAltException(this); + } } } catch (re) { @@ -709,13 +734,13 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 195; + this.state = 197; this.match(FmlMappingParser.METADATA_PREFIX); - this.state = 196; + this.state = 198; this.qualifiedIdentifier(); - this.state = 197; + this.state = 199; this.match(FmlMappingParser.T__4); - this.state = 200; + this.state = 202; this._errHandler.sync(this); switch (this._input.LA(1)) { case 89: @@ -729,13 +754,13 @@ export default class FmlMappingParser extends Parser { case 100: case 101: { - this.state = 198; + this.state = 200; this.literal(); } break; case 102: { - this.state = 199; + this.state = 201; this.markdownLiteral(); } break; @@ -773,7 +798,7 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 202; + this.state = 204; this.match(FmlMappingParser.TRIPLE_QUOTED_STRING_LITERAL); } } @@ -799,7 +824,7 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 204; + this.state = 206; _la = this._input.LA(1); if(!(_la===100 || _la===101)) { this._errHandler.recoverInline(this); @@ -832,7 +857,7 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 206; + this.state = 208; _la = this._input.LA(1); if(!((((_la) & ~0x1F) === 0 && ((1 << _la) & 65024) !== 0) || ((((_la - 97)) & ~0x1F) === 0 && ((1 << (_la - 97)) & 7) !== 0))) { this._errHandler.recoverInline(this); @@ -865,25 +890,25 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 208; + this.state = 210; this.match(FmlMappingParser.T__15); - this.state = 209; + this.state = 211; this.url(); - this.state = 212; + this.state = 214; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===17) { { - this.state = 210; + this.state = 212; this.match(FmlMappingParser.T__16); - this.state = 211; + this.state = 213; this.identifier(); } } - this.state = 214; + this.state = 216; this.match(FmlMappingParser.T__8); - this.state = 215; + this.state = 217; this.modelMode(); } } @@ -908,15 +933,15 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 217; + this.state = 219; this.match(FmlMappingParser.T__17); - this.state = 218; + this.state = 220; this.match(FmlMappingParser.ID); - this.state = 219; + this.state = 221; this.match(FmlMappingParser.T__4); - this.state = 220; + this.state = 222; this.fpExpression(0); - this.state = 221; + this.state = 223; this.match(FmlMappingParser.T__18); } } @@ -942,33 +967,33 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 223; + this.state = 225; this.match(FmlMappingParser.T__19); - this.state = 224; + this.state = 226; this.match(FmlMappingParser.ID); - this.state = 225; - this.parameters(); this.state = 227; + this.parameters(); + this.state = 229; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===26) { { - this.state = 226; + this.state = 228; this.extends_(); } } - this.state = 230; + this.state = 232; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===24) { { - this.state = 229; + this.state = 231; this.typeMode(); } } - this.state = 232; + this.state = 234; this.mapRules(); } } @@ -994,27 +1019,27 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 234; + this.state = 236; this.match(FmlMappingParser.T__20); - this.state = 235; + this.state = 237; this.parameter(); - this.state = 238; + this.state = 240; this._errHandler.sync(this); _la = this._input.LA(1); do { { { - this.state = 236; + this.state = 238; this.match(FmlMappingParser.T__21); - this.state = 237; + this.state = 239; this.parameter(); } } - this.state = 240; + this.state = 242; this._errHandler.sync(this); _la = this._input.LA(1); } while (_la===22); - this.state = 242; + this.state = 244; this.match(FmlMappingParser.T__22); } } @@ -1040,16 +1065,16 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 244; + this.state = 246; this.parameterMode(); - this.state = 245; - this.match(FmlMappingParser.ID); this.state = 247; + this.match(FmlMappingParser.ID); + this.state = 249; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===7) { { - this.state = 246; + this.state = 248; this.typeIdentifier(); } } @@ -1078,23 +1103,23 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 249; + this.state = 251; this.match(FmlMappingParser.T__1); - this.state = 253; + this.state = 255; this._errHandler.sync(this); _la = this._input.LA(1); while ((((_la) & ~0x1F) === 0 && ((1 << _la) & 3289904912) !== 0) || ((((_la - 32)) & ~0x1F) === 0 && ((1 << (_la - 32)) & 127) !== 0) || _la===97 || _la===98) { { { - this.state = 250; + this.state = 252; this.mapRule(); } } - this.state = 255; + this.state = 257; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 256; + this.state = 258; this.match(FmlMappingParser.T__2); } } @@ -1119,11 +1144,11 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 258; + this.state = 260; this.match(FmlMappingParser.T__23); - this.state = 259; + this.state = 261; this.groupTypeMode(); - this.state = 260; + this.state = 262; this.match(FmlMappingParser.T__24); } } @@ -1148,9 +1173,9 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 262; + this.state = 264; this.match(FmlMappingParser.T__25); - this.state = 263; + this.state = 265; this.match(FmlMappingParser.ID); } } @@ -1175,9 +1200,9 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 265; + this.state = 267; this.match(FmlMappingParser.T__6); - this.state = 266; + this.state = 268; this.identifier(); } } @@ -1201,30 +1226,30 @@ export default class FmlMappingParser extends Parser { this.enterRule(localctx, 42, FmlMappingParser.RULE_mapRule); let _la: number; try { - this.state = 279; + this.state = 281; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 17, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 18, this._ctx) ) { case 1: localctx = new MapSimpleCopyContext(this, localctx); this.enterOuterAlt(localctx, 1); { - this.state = 268; - this.qualifiedIdentifier(); - this.state = 269; - this.match(FmlMappingParser.T__26); this.state = 270; this.qualifiedIdentifier(); + this.state = 271; + this.match(FmlMappingParser.T__26); this.state = 272; + this.qualifiedIdentifier(); + this.state = 274; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===101) { { - this.state = 271; + this.state = 273; this.ruleName(); } } - this.state = 274; + this.state = 276; this.match(FmlMappingParser.T__18); } break; @@ -1232,9 +1257,9 @@ export default class FmlMappingParser extends Parser { localctx = new MapFhirMarkupContext(this, localctx); this.enterOuterAlt(localctx, 2); { - this.state = 276; + this.state = 278; this.mapTransformationRule(); - this.state = 277; + this.state = 279; this.match(FmlMappingParser.T__18); } break; @@ -1262,36 +1287,36 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 281; + this.state = 283; this.ruleSources(); - this.state = 284; + this.state = 286; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===27) { { - this.state = 282; + this.state = 284; this.match(FmlMappingParser.T__26); - this.state = 283; + this.state = 285; this.ruleTargets(); } } - this.state = 287; + this.state = 289; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===42) { { - this.state = 286; + this.state = 288; this.dependentExpression(); } } - this.state = 290; + this.state = 292; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===101) { { - this.state = 289; + this.state = 291; this.ruleName(); } } @@ -1319,7 +1344,7 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 292; + this.state = 294; this.match(FmlMappingParser.DOUBLE_QUOTED_STRING); } } @@ -1345,21 +1370,21 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 294; + this.state = 296; this.ruleSource(); - this.state = 299; + this.state = 301; this._errHandler.sync(this); _la = this._input.LA(1); while (_la===22) { { { - this.state = 295; + this.state = 297; this.match(FmlMappingParser.T__21); - this.state = 296; + this.state = 298; this.ruleSource(); } } - this.state = 301; + this.state = 303; this._errHandler.sync(this); _la = this._input.LA(1); } @@ -1387,84 +1412,84 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 302; - this.qualifiedIdentifier(); this.state = 304; + this.qualifiedIdentifier(); + this.state = 306; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===7) { { - this.state = 303; + this.state = 305; this.typeIdentifier(); } } - this.state = 307; + this.state = 309; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===96) { { - this.state = 306; + this.state = 308; this.sourceCardinality(); } } - this.state = 310; + this.state = 312; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===40) { { - this.state = 309; + this.state = 311; this.sourceDefault(); } } - this.state = 313; + this.state = 315; this._errHandler.sync(this); _la = this._input.LA(1); if (((((_la - 37)) & ~0x1F) === 0 && ((1 << (_la - 37)) & 1879048195) !== 0)) { { - this.state = 312; + this.state = 314; this.sourceListMode(); } } - this.state = 316; + this.state = 318; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===9) { { - this.state = 315; + this.state = 317; this.alias(); } } - this.state = 319; + this.state = 321; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===34) { { - this.state = 318; + this.state = 320; this.whereClause(); } } - this.state = 322; + this.state = 324; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===35) { { - this.state = 321; + this.state = 323; this.checkClause(); } } - this.state = 325; + this.state = 327; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===41) { { - this.state = 324; + this.state = 326; this.log(); } } @@ -1493,21 +1518,21 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 327; + this.state = 329; this.ruleTarget(); - this.state = 332; + this.state = 334; this._errHandler.sync(this); _la = this._input.LA(1); while (_la===22) { { { - this.state = 328; + this.state = 330; this.match(FmlMappingParser.T__21); - this.state = 329; + this.state = 331; this.ruleTarget(); } } - this.state = 334; + this.state = 336; this._errHandler.sync(this); _la = this._input.LA(1); } @@ -1533,42 +1558,42 @@ export default class FmlMappingParser extends Parser { this.enterRule(localctx, 54, FmlMappingParser.RULE_ruleTarget); let _la: number; try { - this.state = 359; + this.state = 361; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 37, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 38, this._ctx) ) { case 1: this.enterOuterAlt(localctx, 1); { - this.state = 335; + this.state = 337; this.qualifiedIdentifier(); - this.state = 338; + this.state = 340; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===5) { { - this.state = 336; + this.state = 338; this.match(FmlMappingParser.T__4); - this.state = 337; + this.state = 339; this.transform(); } } - this.state = 341; + this.state = 343; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===9) { { - this.state = 340; + this.state = 342; this.alias(); } } - this.state = 344; + this.state = 346; this._errHandler.sync(this); _la = this._input.LA(1); if (((((_la - 37)) & ~0x1F) === 0 && ((1 << (_la - 37)) & 2147483651) !== 0) || _la===69) { { - this.state = 343; + this.state = 345; this.targetListMode(); } } @@ -1578,28 +1603,28 @@ export default class FmlMappingParser extends Parser { case 2: this.enterOuterAlt(localctx, 2); { - this.state = 346; + this.state = 348; this.match(FmlMappingParser.T__20); - this.state = 347; + this.state = 349; this.fpExpression(0); - this.state = 348; - this.match(FmlMappingParser.T__22); this.state = 350; + this.match(FmlMappingParser.T__22); + this.state = 352; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===9) { { - this.state = 349; + this.state = 351; this.alias(); } } - this.state = 353; + this.state = 355; this._errHandler.sync(this); _la = this._input.LA(1); if (((((_la - 37)) & ~0x1F) === 0 && ((1 << (_la - 37)) & 2147483651) !== 0) || _la===69) { { - this.state = 352; + this.state = 354; this.targetListMode(); } } @@ -1609,14 +1634,14 @@ export default class FmlMappingParser extends Parser { case 3: this.enterOuterAlt(localctx, 3); { - this.state = 355; - this.groupInvocation(); this.state = 357; + this.groupInvocation(); + this.state = 359; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===9) { { - this.state = 356; + this.state = 358; this.alias(); } } @@ -1646,11 +1671,11 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 361; + this.state = 363; this.match(FmlMappingParser.INTEGER); - this.state = 362; + this.state = 364; this.match(FmlMappingParser.T__27); - this.state = 363; + this.state = 365; this.upperBound(); } } @@ -1676,7 +1701,7 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 365; + this.state = 367; _la = this._input.LA(1); if(!(_la===29 || _la===96)) { this._errHandler.recoverInline(this); @@ -1710,7 +1735,7 @@ export default class FmlMappingParser extends Parser { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 367; + this.state = 369; _la = this._input.LA(1); if(!((((_la) & ~0x1F) === 0 && ((1 << _la) & 3289904912) !== 0) || ((((_la - 32)) & ~0x1F) === 0 && ((1 << (_la - 32)) & 127) !== 0) || _la===97 || _la===98)) { this._errHandler.recoverInline(this); @@ -1719,16 +1744,16 @@ export default class FmlMappingParser extends Parser { this._errHandler.reportMatch(this); this.consume(); } - this.state = 372; + this.state = 374; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 38, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 39, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 368; + this.state = 370; this.match(FmlMappingParser.T__38); - this.state = 369; + this.state = 371; _la = this._input.LA(1); if(!((((_la) & ~0x1F) === 0 && ((1 << _la) & 3289904912) !== 0) || ((((_la - 32)) & ~0x1F) === 0 && ((1 << (_la - 32)) & 127) !== 0) || _la===97 || _la===98)) { this._errHandler.recoverInline(this); @@ -1740,9 +1765,9 @@ export default class FmlMappingParser extends Parser { } } } - this.state = 374; + this.state = 376; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 38, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 39, this._ctx); } } } @@ -1765,28 +1790,28 @@ export default class FmlMappingParser extends Parser { let localctx: SourceDefaultContext = new SourceDefaultContext(this, this._ctx, this.state); this.enterRule(localctx, 62, FmlMappingParser.RULE_sourceDefault); try { - this.state = 382; + this.state = 384; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 39, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 40, this._ctx) ) { case 1: this.enterOuterAlt(localctx, 1); { - this.state = 375; + this.state = 377; this.match(FmlMappingParser.T__39); - this.state = 376; + this.state = 378; this.match(FmlMappingParser.T__20); - this.state = 377; + this.state = 379; this.fpExpression(0); - this.state = 378; + this.state = 380; this.match(FmlMappingParser.T__22); } break; case 2: this.enterOuterAlt(localctx, 2); { - this.state = 380; + this.state = 382; this.match(FmlMappingParser.T__39); - this.state = 381; + this.state = 383; this.match(FmlMappingParser.DOUBLE_QUOTED_STRING); } break; @@ -1813,9 +1838,9 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 384; + this.state = 386; this.match(FmlMappingParser.T__8); - this.state = 385; + this.state = 387; this.identifier(); } } @@ -1840,13 +1865,13 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 387; + this.state = 389; this.match(FmlMappingParser.T__33); - this.state = 388; + this.state = 390; this.match(FmlMappingParser.T__20); - this.state = 389; + this.state = 391; this.fpExpression(0); - this.state = 390; + this.state = 392; this.match(FmlMappingParser.T__22); } } @@ -1871,13 +1896,13 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 392; + this.state = 394; this.match(FmlMappingParser.T__34); - this.state = 393; + this.state = 395; this.match(FmlMappingParser.T__20); - this.state = 394; + this.state = 396; this.fpExpression(0); - this.state = 395; + this.state = 397; this.match(FmlMappingParser.T__22); } } @@ -1902,13 +1927,13 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 397; + this.state = 399; this.match(FmlMappingParser.T__40); - this.state = 398; + this.state = 400; this.match(FmlMappingParser.T__20); - this.state = 399; + this.state = 401; this.fpExpression(0); - this.state = 400; + this.state = 402; this.match(FmlMappingParser.T__22); } } @@ -1934,9 +1959,9 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 402; + this.state = 404; this.match(FmlMappingParser.T__41); - this.state = 415; + this.state = 417; this._errHandler.sync(this); switch (this._input.LA(1)) { case 9: @@ -1950,30 +1975,30 @@ export default class FmlMappingParser extends Parser { case 98: case 99: { - this.state = 403; + this.state = 405; this.groupInvocation(); - this.state = 408; + this.state = 410; this._errHandler.sync(this); _la = this._input.LA(1); while (_la===22) { { { - this.state = 404; + this.state = 406; this.match(FmlMappingParser.T__21); - this.state = 405; + this.state = 407; this.groupInvocation(); } } - this.state = 410; + this.state = 412; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 412; + this.state = 414; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===2) { { - this.state = 411; + this.state = 413; this.mapRules(); } } @@ -1982,7 +2007,7 @@ export default class FmlMappingParser extends Parser { break; case 2: { - this.state = 414; + this.state = 416; this.mapRules(); } break; @@ -2012,9 +2037,9 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 417; + this.state = 419; this.match(FmlMappingParser.T__29); - this.state = 418; + this.state = 420; this.url(); } } @@ -2037,38 +2062,38 @@ export default class FmlMappingParser extends Parser { let localctx: TransformContext = new TransformContext(this, this._ctx, this.state); this.enterRule(localctx, 76, FmlMappingParser.RULE_transform); try { - this.state = 427; + this.state = 429; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 43, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 44, this._ctx) ) { case 1: this.enterOuterAlt(localctx, 1); { - this.state = 420; + this.state = 422; this.literal(); } break; case 2: this.enterOuterAlt(localctx, 2); { - this.state = 421; + this.state = 423; this.qualifiedIdentifier(); } break; case 3: this.enterOuterAlt(localctx, 3); { - this.state = 422; + this.state = 424; this.groupInvocation(); } break; case 4: this.enterOuterAlt(localctx, 4); { - this.state = 423; + this.state = 425; this.match(FmlMappingParser.T__20); - this.state = 424; + this.state = 426; this.fpExpression(0); - this.state = 425; + this.state = 427; this.match(FmlMappingParser.T__22); } break; @@ -2096,21 +2121,21 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 429; + this.state = 431; this.identifier(); - this.state = 430; - this.match(FmlMappingParser.T__20); this.state = 432; + this.match(FmlMappingParser.T__20); + this.state = 434; this._errHandler.sync(this); _la = this._input.LA(1); if (((((_la - 89)) & ~0x1F) === 0 && ((1 << (_la - 89)) & 6655) !== 0)) { { - this.state = 431; + this.state = 433; this.groupParamList(); } } - this.state = 434; + this.state = 436; this.match(FmlMappingParser.T__22); } } @@ -2136,21 +2161,21 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 436; + this.state = 438; this.groupParam(); - this.state = 441; + this.state = 443; this._errHandler.sync(this); _la = this._input.LA(1); while (_la===22) { { { - this.state = 437; + this.state = 439; this.match(FmlMappingParser.T__21); - this.state = 438; + this.state = 440; this.groupParam(); } } - this.state = 443; + this.state = 445; this._errHandler.sync(this); _la = this._input.LA(1); } @@ -2175,7 +2200,7 @@ export default class FmlMappingParser extends Parser { let localctx: GroupParamContext = new GroupParamContext(this, this._ctx, this.state); this.enterRule(localctx, 82, FmlMappingParser.RULE_groupParam); try { - this.state = 446; + this.state = 448; this._errHandler.sync(this); switch (this._input.LA(1)) { case 89: @@ -2190,14 +2215,14 @@ export default class FmlMappingParser extends Parser { case 101: this.enterOuterAlt(localctx, 1); { - this.state = 444; + this.state = 446; this.literal(); } break; case 97: this.enterOuterAlt(localctx, 2); { - this.state = 445; + this.state = 447; this.match(FmlMappingParser.ID); } break; @@ -2239,7 +2264,7 @@ export default class FmlMappingParser extends Parser { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 452; + this.state = 454; this._errHandler.sync(this); switch (this._input.LA(1)) { case 4: @@ -2288,7 +2313,7 @@ export default class FmlMappingParser extends Parser { this._ctx = localctx; _prevctx = localctx; - this.state = 449; + this.state = 451; this.fpTerm(); } break; @@ -2298,7 +2323,7 @@ export default class FmlMappingParser extends Parser { localctx = new PolarityExpressionContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 450; + this.state = 452; _la = this._input.LA(1); if(!(_la===6 || _la===45)) { this._errHandler.recoverInline(this); @@ -2307,7 +2332,7 @@ export default class FmlMappingParser extends Parser { this._errHandler.reportMatch(this); this.consume(); } - this.state = 451; + this.state = 453; this.fpExpression(11); } break; @@ -2315,9 +2340,9 @@ export default class FmlMappingParser extends Parser { throw new NoViableAltException(this); } this._ctx.stop = this._input.LT(-1); - this.state = 494; + this.state = 496; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 49, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 50, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { if (this._parseListeners != null) { @@ -2325,18 +2350,18 @@ export default class FmlMappingParser extends Parser { } _prevctx = localctx; { - this.state = 492; + this.state = 494; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 48, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 49, this._ctx) ) { case 1: { localctx = new MultiplicativeExpressionContext(this, new FpExpressionContext(this, _parentctx, _parentState)); this.pushNewRecursionContext(localctx, _startState, FmlMappingParser.RULE_fpExpression); - this.state = 454; + this.state = 456; if (!(this.precpred(this._ctx, 10))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 10)"); } - this.state = 455; + this.state = 457; _la = this._input.LA(1); if(!(((((_la - 29)) & ~0x1F) === 0 && ((1 << (_la - 29)) & 393345) !== 0))) { this._errHandler.recoverInline(this); @@ -2345,7 +2370,7 @@ export default class FmlMappingParser extends Parser { this._errHandler.reportMatch(this); this.consume(); } - this.state = 456; + this.state = 458; this.fpExpression(11); } break; @@ -2353,11 +2378,11 @@ export default class FmlMappingParser extends Parser { { localctx = new AdditiveExpressionContext(this, new FpExpressionContext(this, _parentctx, _parentState)); this.pushNewRecursionContext(localctx, _startState, FmlMappingParser.RULE_fpExpression); - this.state = 457; + this.state = 459; if (!(this.precpred(this._ctx, 9))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 9)"); } - this.state = 458; + this.state = 460; _la = this._input.LA(1); if(!(_la===6 || _la===45 || _la===48)) { this._errHandler.recoverInline(this); @@ -2366,7 +2391,7 @@ export default class FmlMappingParser extends Parser { this._errHandler.reportMatch(this); this.consume(); } - this.state = 459; + this.state = 461; this.fpExpression(10); } break; @@ -2374,15 +2399,15 @@ export default class FmlMappingParser extends Parser { { localctx = new UnionExpressionContext(this, new FpExpressionContext(this, _parentctx, _parentState)); this.pushNewRecursionContext(localctx, _startState, FmlMappingParser.RULE_fpExpression); - this.state = 460; + this.state = 462; if (!(this.precpred(this._ctx, 7))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 7)"); } { - this.state = 461; + this.state = 463; this.match(FmlMappingParser.T__48); } - this.state = 462; + this.state = 464; this.fpExpression(8); } break; @@ -2390,11 +2415,11 @@ export default class FmlMappingParser extends Parser { { localctx = new InequalityExpressionContext(this, new FpExpressionContext(this, _parentctx, _parentState)); this.pushNewRecursionContext(localctx, _startState, FmlMappingParser.RULE_fpExpression); - this.state = 463; + this.state = 465; if (!(this.precpred(this._ctx, 6))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 6)"); } - this.state = 464; + this.state = 466; _la = this._input.LA(1); if(!(((((_la - 50)) & ~0x1F) === 0 && ((1 << (_la - 50)) & 15) !== 0))) { this._errHandler.recoverInline(this); @@ -2403,7 +2428,7 @@ export default class FmlMappingParser extends Parser { this._errHandler.reportMatch(this); this.consume(); } - this.state = 465; + this.state = 467; this.fpExpression(7); } break; @@ -2411,11 +2436,11 @@ export default class FmlMappingParser extends Parser { { localctx = new EqualityExpressionContext(this, new FpExpressionContext(this, _parentctx, _parentState)); this.pushNewRecursionContext(localctx, _startState, FmlMappingParser.RULE_fpExpression); - this.state = 466; + this.state = 468; if (!(this.precpred(this._ctx, 5))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 5)"); } - this.state = 467; + this.state = 469; _la = this._input.LA(1); if(!(_la===5 || ((((_la - 54)) & ~0x1F) === 0 && ((1 << (_la - 54)) & 7) !== 0))) { this._errHandler.recoverInline(this); @@ -2424,7 +2449,7 @@ export default class FmlMappingParser extends Parser { this._errHandler.reportMatch(this); this.consume(); } - this.state = 468; + this.state = 470; this.fpExpression(6); } break; @@ -2432,11 +2457,11 @@ export default class FmlMappingParser extends Parser { { localctx = new MembershipExpressionContext(this, new FpExpressionContext(this, _parentctx, _parentState)); this.pushNewRecursionContext(localctx, _startState, FmlMappingParser.RULE_fpExpression); - this.state = 469; + this.state = 471; if (!(this.precpred(this._ctx, 4))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 4)"); } - this.state = 470; + this.state = 472; _la = this._input.LA(1); if(!(_la===10 || _la===11)) { this._errHandler.recoverInline(this); @@ -2445,7 +2470,7 @@ export default class FmlMappingParser extends Parser { this._errHandler.reportMatch(this); this.consume(); } - this.state = 471; + this.state = 473; this.fpExpression(5); } break; @@ -2453,15 +2478,15 @@ export default class FmlMappingParser extends Parser { { localctx = new AndExpressionContext(this, new FpExpressionContext(this, _parentctx, _parentState)); this.pushNewRecursionContext(localctx, _startState, FmlMappingParser.RULE_fpExpression); - this.state = 472; + this.state = 474; if (!(this.precpred(this._ctx, 3))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 3)"); } { - this.state = 473; + this.state = 475; this.match(FmlMappingParser.T__56); } - this.state = 474; + this.state = 476; this.fpExpression(4); } break; @@ -2469,11 +2494,11 @@ export default class FmlMappingParser extends Parser { { localctx = new OrExpressionContext(this, new FpExpressionContext(this, _parentctx, _parentState)); this.pushNewRecursionContext(localctx, _startState, FmlMappingParser.RULE_fpExpression); - this.state = 475; + this.state = 477; if (!(this.precpred(this._ctx, 2))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 2)"); } - this.state = 476; + this.state = 478; _la = this._input.LA(1); if(!(_la===58 || _la===59)) { this._errHandler.recoverInline(this); @@ -2482,7 +2507,7 @@ export default class FmlMappingParser extends Parser { this._errHandler.reportMatch(this); this.consume(); } - this.state = 477; + this.state = 479; this.fpExpression(3); } break; @@ -2490,15 +2515,15 @@ export default class FmlMappingParser extends Parser { { localctx = new ImpliesExpressionContext(this, new FpExpressionContext(this, _parentctx, _parentState)); this.pushNewRecursionContext(localctx, _startState, FmlMappingParser.RULE_fpExpression); - this.state = 478; + this.state = 480; if (!(this.precpred(this._ctx, 1))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 1)"); } { - this.state = 479; + this.state = 481; this.match(FmlMappingParser.T__59); } - this.state = 480; + this.state = 482; this.fpExpression(2); } break; @@ -2506,13 +2531,13 @@ export default class FmlMappingParser extends Parser { { localctx = new InvocationExpressionContext(this, new FpExpressionContext(this, _parentctx, _parentState)); this.pushNewRecursionContext(localctx, _startState, FmlMappingParser.RULE_fpExpression); - this.state = 481; + this.state = 483; if (!(this.precpred(this._ctx, 13))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 13)"); } - this.state = 482; + this.state = 484; this.match(FmlMappingParser.T__38); - this.state = 483; + this.state = 485; this.fpInvocation(); } break; @@ -2520,15 +2545,15 @@ export default class FmlMappingParser extends Parser { { localctx = new IndexerExpressionContext(this, new FpExpressionContext(this, _parentctx, _parentState)); this.pushNewRecursionContext(localctx, _startState, FmlMappingParser.RULE_fpExpression); - this.state = 484; + this.state = 486; if (!(this.precpred(this._ctx, 12))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 12)"); } - this.state = 485; + this.state = 487; this.match(FmlMappingParser.T__42); - this.state = 486; + this.state = 488; this.fpExpression(0); - this.state = 487; + this.state = 489; this.match(FmlMappingParser.T__43); } break; @@ -2536,11 +2561,11 @@ export default class FmlMappingParser extends Parser { { localctx = new TypeExpressionContext(this, new FpExpressionContext(this, _parentctx, _parentState)); this.pushNewRecursionContext(localctx, _startState, FmlMappingParser.RULE_fpExpression); - this.state = 489; + this.state = 491; if (!(this.precpred(this._ctx, 8))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 8)"); } - this.state = 490; + this.state = 492; _la = this._input.LA(1); if(!(_la===9 || _la===12)) { this._errHandler.recoverInline(this); @@ -2549,16 +2574,16 @@ export default class FmlMappingParser extends Parser { this._errHandler.reportMatch(this); this.consume(); } - this.state = 491; + this.state = 493; this.fpTypeSpecifier(); } break; } } } - this.state = 496; + this.state = 498; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 49, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 50, this._ctx); } } } @@ -2581,7 +2606,7 @@ export default class FmlMappingParser extends Parser { let localctx: FpTermContext = new FpTermContext(this, this._ctx, this.state); this.enterRule(localctx, 86, FmlMappingParser.RULE_fpTerm); try { - this.state = 504; + this.state = 506; this._errHandler.sync(this); switch (this._input.LA(1)) { case 4: @@ -2616,7 +2641,7 @@ export default class FmlMappingParser extends Parser { localctx = new InvocationTermContext(this, localctx); this.enterOuterAlt(localctx, 1); { - this.state = 497; + this.state = 499; this.fpInvocation(); } break; @@ -2633,7 +2658,7 @@ export default class FmlMappingParser extends Parser { localctx = new LiteralTermContext(this, localctx); this.enterOuterAlt(localctx, 2); { - this.state = 498; + this.state = 500; this.literal(); } break; @@ -2641,7 +2666,7 @@ export default class FmlMappingParser extends Parser { localctx = new ExternalConstantTermContext(this, localctx); this.enterOuterAlt(localctx, 3); { - this.state = 499; + this.state = 501; this.fpExternalConstant(); } break; @@ -2649,11 +2674,11 @@ export default class FmlMappingParser extends Parser { localctx = new ParenthesizedTermContext(this, localctx); this.enterOuterAlt(localctx, 4); { - this.state = 500; + this.state = 502; this.match(FmlMappingParser.T__20); - this.state = 501; + this.state = 503; this.fpExpression(0); - this.state = 502; + this.state = 504; this.match(FmlMappingParser.T__22); } break; @@ -2680,14 +2705,14 @@ export default class FmlMappingParser extends Parser { let localctx: FpInvocationContext = new FpInvocationContext(this, this._ctx, this.state); this.enterRule(localctx, 88, FmlMappingParser.RULE_fpInvocation); try { - this.state = 511; + this.state = 513; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 51, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 52, this._ctx) ) { case 1: localctx = new FunctionInvocationContext(this, localctx); this.enterOuterAlt(localctx, 1); { - this.state = 506; + this.state = 508; this.fpFunction(); } break; @@ -2695,7 +2720,7 @@ export default class FmlMappingParser extends Parser { localctx = new MemberInvocationContext(this, localctx); this.enterOuterAlt(localctx, 2); { - this.state = 507; + this.state = 509; this.identifier(); } break; @@ -2703,7 +2728,7 @@ export default class FmlMappingParser extends Parser { localctx = new ThisInvocationContext(this, localctx); this.enterOuterAlt(localctx, 3); { - this.state = 508; + this.state = 510; this.match(FmlMappingParser.T__60); } break; @@ -2711,7 +2736,7 @@ export default class FmlMappingParser extends Parser { localctx = new IndexInvocationContext(this, localctx); this.enterOuterAlt(localctx, 4); { - this.state = 509; + this.state = 511; this.match(FmlMappingParser.T__61); } break; @@ -2719,7 +2744,7 @@ export default class FmlMappingParser extends Parser { localctx = new TotalInvocationContext(this, localctx); this.enterOuterAlt(localctx, 5); { - this.state = 510; + this.state = 512; this.match(FmlMappingParser.T__62); } break; @@ -2746,9 +2771,9 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 513; + this.state = 515; this.match(FmlMappingParser.T__63); - this.state = 516; + this.state = 518; this._errHandler.sync(this); switch (this._input.LA(1)) { case 9: @@ -2762,13 +2787,13 @@ export default class FmlMappingParser extends Parser { case 98: case 99: { - this.state = 514; + this.state = 516; this.identifier(); } break; case 100: { - this.state = 515; + this.state = 517; this.match(FmlMappingParser.STRING); } break; @@ -2797,64 +2822,64 @@ export default class FmlMappingParser extends Parser { this.enterRule(localctx, 92, FmlMappingParser.RULE_fpFunction); let _la: number; try { - this.state = 538; + this.state = 540; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 56, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 57, this._ctx) ) { case 1: this.enterOuterAlt(localctx, 1); { - this.state = 518; + this.state = 520; this.match(FmlMappingParser.T__14); - this.state = 519; + this.state = 521; this.match(FmlMappingParser.T__20); - this.state = 528; + this.state = 530; this._errHandler.sync(this); _la = this._input.LA(1); if (((((_la - 4)) & ~0x1F) === 0 && ((1 << (_la - 4)) & 4232282101) !== 0) || ((((_la - 36)) & ~0x1F) === 0 && ((1 << (_la - 36)) & 503316999) !== 0) || ((((_la - 89)) & ~0x1F) === 0 && ((1 << (_la - 89)) & 8191) !== 0)) { { - this.state = 520; + this.state = 522; this.fpSortArgument(); - this.state = 525; + this.state = 527; this._errHandler.sync(this); _la = this._input.LA(1); while (_la===22) { { { - this.state = 521; + this.state = 523; this.match(FmlMappingParser.T__21); - this.state = 522; + this.state = 524; this.fpSortArgument(); } } - this.state = 527; + this.state = 529; this._errHandler.sync(this); _la = this._input.LA(1); } } } - this.state = 530; + this.state = 532; this.match(FmlMappingParser.T__22); } break; case 2: this.enterOuterAlt(localctx, 2); { - this.state = 531; + this.state = 533; this.qualifiedIdentifier(); - this.state = 532; - this.match(FmlMappingParser.T__20); this.state = 534; + this.match(FmlMappingParser.T__20); + this.state = 536; this._errHandler.sync(this); _la = this._input.LA(1); if (((((_la - 4)) & ~0x1F) === 0 && ((1 << (_la - 4)) & 4232282101) !== 0) || ((((_la - 36)) & ~0x1F) === 0 && ((1 << (_la - 36)) & 503316999) !== 0) || ((((_la - 89)) & ~0x1F) === 0 && ((1 << (_la - 89)) & 8191) !== 0)) { { - this.state = 533; + this.state = 535; this.fpParamList(); } } - this.state = 536; + this.state = 538; this.match(FmlMappingParser.T__22); } break; @@ -2883,14 +2908,14 @@ export default class FmlMappingParser extends Parser { localctx = new SortDirectionArgumentContext(this, localctx); this.enterOuterAlt(localctx, 1); { - this.state = 540; - this.fpExpression(0); this.state = 542; + this.fpExpression(0); + this.state = 544; this._errHandler.sync(this); _la = this._input.LA(1); if (_la===13 || _la===14) { { - this.state = 541; + this.state = 543; _la = this._input.LA(1); if(!(_la===13 || _la===14)) { this._errHandler.recoverInline(this); @@ -2926,21 +2951,21 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 544; + this.state = 546; this.fpExpression(0); - this.state = 549; + this.state = 551; this._errHandler.sync(this); _la = this._input.LA(1); while (_la===22) { { { - this.state = 545; + this.state = 547; this.match(FmlMappingParser.T__21); - this.state = 546; + this.state = 548; this.fpExpression(0); } } - this.state = 551; + this.state = 553; this._errHandler.sync(this); _la = this._input.LA(1); } @@ -2967,7 +2992,7 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 552; + this.state = 554; this.qualifiedIdentifier(); } } @@ -2992,7 +3017,7 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 554; + this.state = 556; this.match(FmlMappingParser.ID); } } @@ -3018,7 +3043,7 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 556; + this.state = 558; _la = this._input.LA(1); if(!(((((_la - 37)) & ~0x1F) === 0 && ((1 << (_la - 37)) & 1879048195) !== 0))) { this._errHandler.recoverInline(this); @@ -3051,7 +3076,7 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 558; + this.state = 560; _la = this._input.LA(1); if(!(((((_la - 37)) & ~0x1F) === 0 && ((1 << (_la - 37)) & 2147483651) !== 0) || _la===69)) { this._errHandler.recoverInline(this); @@ -3084,7 +3109,7 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 560; + this.state = 562; _la = this._input.LA(1); if(!(_la===33 || _la===70)) { this._errHandler.recoverInline(this); @@ -3117,7 +3142,7 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 562; + this.state = 564; _la = this._input.LA(1); if(!(_la===31 || _la===32 || _la===71 || _la===72)) { this._errHandler.recoverInline(this); @@ -3150,7 +3175,7 @@ export default class FmlMappingParser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 564; + this.state = 566; _la = this._input.LA(1); if(!(_la===31 || _la===32)) { this._errHandler.recoverInline(this); @@ -3181,14 +3206,14 @@ export default class FmlMappingParser extends Parser { this.enterRule(localctx, 112, FmlMappingParser.RULE_literal); let _la: number; try { - this.state = 576; + this.state = 578; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 59, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 60, this._ctx) ) { case 1: localctx = new NullLiteralContext(this, localctx); this.enterOuterAlt(localctx, 1); { - this.state = 566; + this.state = 568; this.match(FmlMappingParser.NULL_LITERAL); } break; @@ -3196,7 +3221,7 @@ export default class FmlMappingParser extends Parser { localctx = new BooleanLiteralContext(this, localctx); this.enterOuterAlt(localctx, 2); { - this.state = 567; + this.state = 569; this.match(FmlMappingParser.BOOL); } break; @@ -3204,7 +3229,7 @@ export default class FmlMappingParser extends Parser { localctx = new QuantityLiteralContext(this, localctx); this.enterOuterAlt(localctx, 3); { - this.state = 568; + this.state = 570; this.fpQuantity(); } break; @@ -3212,7 +3237,7 @@ export default class FmlMappingParser extends Parser { localctx = new LongNumberLiteralContext(this, localctx); this.enterOuterAlt(localctx, 4); { - this.state = 569; + this.state = 571; this.match(FmlMappingParser.LONGNUMBER); } break; @@ -3220,7 +3245,7 @@ export default class FmlMappingParser extends Parser { localctx = new NumberLiteralContext(this, localctx); this.enterOuterAlt(localctx, 5); { - this.state = 570; + this.state = 572; _la = this._input.LA(1); if(!(_la===95 || _la===96)) { this._errHandler.recoverInline(this); @@ -3235,7 +3260,7 @@ export default class FmlMappingParser extends Parser { localctx = new DateLiteralContext(this, localctx); this.enterOuterAlt(localctx, 6); { - this.state = 571; + this.state = 573; this.match(FmlMappingParser.DATE); } break; @@ -3243,7 +3268,7 @@ export default class FmlMappingParser extends Parser { localctx = new DateTimeLiteralContext(this, localctx); this.enterOuterAlt(localctx, 7); { - this.state = 572; + this.state = 574; this.match(FmlMappingParser.DATETIME); } break; @@ -3251,7 +3276,7 @@ export default class FmlMappingParser extends Parser { localctx = new TimeLiteralContext(this, localctx); this.enterOuterAlt(localctx, 8); { - this.state = 573; + this.state = 575; this.match(FmlMappingParser.TIME); } break; @@ -3259,7 +3284,7 @@ export default class FmlMappingParser extends Parser { localctx = new StringLiteralContext(this, localctx); this.enterOuterAlt(localctx, 9); { - this.state = 574; + this.state = 576; this.match(FmlMappingParser.STRING); } break; @@ -3267,7 +3292,7 @@ export default class FmlMappingParser extends Parser { localctx = new QuotedStringLiteralContext(this, localctx); this.enterOuterAlt(localctx, 10); { - this.state = 575; + this.state = 577; this.match(FmlMappingParser.DOUBLE_QUOTED_STRING); } break; @@ -3293,14 +3318,14 @@ export default class FmlMappingParser extends Parser { this.enterRule(localctx, 114, FmlMappingParser.RULE_fpQuantity); let _la: number; try { - this.state = 584; + this.state = 586; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 60, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 61, this._ctx) ) { case 1: localctx = new QuantityWithDateContext(this, localctx); this.enterOuterAlt(localctx, 1); { - this.state = 578; + this.state = 580; _la = this._input.LA(1); if(!(_la===95 || _la===96)) { this._errHandler.recoverInline(this); @@ -3309,7 +3334,7 @@ export default class FmlMappingParser extends Parser { this._errHandler.reportMatch(this); this.consume(); } - this.state = 579; + this.state = 581; _la = this._input.LA(1); if(!(((((_la - 73)) & ~0x1F) === 0 && ((1 << (_la - 73)) & 255) !== 0))) { this._errHandler.recoverInline(this); @@ -3324,7 +3349,7 @@ export default class FmlMappingParser extends Parser { localctx = new QuantityWithDatePluralContext(this, localctx); this.enterOuterAlt(localctx, 2); { - this.state = 580; + this.state = 582; _la = this._input.LA(1); if(!(_la===95 || _la===96)) { this._errHandler.recoverInline(this); @@ -3333,7 +3358,7 @@ export default class FmlMappingParser extends Parser { this._errHandler.reportMatch(this); this.consume(); } - this.state = 581; + this.state = 583; _la = this._input.LA(1); if(!(((((_la - 81)) & ~0x1F) === 0 && ((1 << (_la - 81)) & 255) !== 0))) { this._errHandler.recoverInline(this); @@ -3348,7 +3373,7 @@ export default class FmlMappingParser extends Parser { localctx = new QuantityWithUcumContext(this, localctx); this.enterOuterAlt(localctx, 3); { - this.state = 582; + this.state = 584; _la = this._input.LA(1); if(!(_la===95 || _la===96)) { this._errHandler.recoverInline(this); @@ -3357,7 +3382,7 @@ export default class FmlMappingParser extends Parser { this._errHandler.reportMatch(this); this.consume(); } - this.state = 583; + this.state = 585; this.match(FmlMappingParser.STRING); } break; @@ -3415,7 +3440,7 @@ export default class FmlMappingParser extends Parser { return true; } - public static readonly _serializedATN: number[] = [4,1,106,587,2,0,7,0, + public static readonly _serializedATN: number[] = [4,1,106,589,2,0,7,0, 2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7,6,2,7,7,7,2,8,7,8,2,9,7,9, 2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13,2,14,7,14,2,15,7,15,2,16,7,16,2, 17,7,17,2,18,7,18,2,19,7,19,2,20,7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24, @@ -3429,189 +3454,190 @@ export default class FmlMappingParser extends Parser { 0,12,0,148,9,0,1,0,4,0,151,8,0,11,0,12,0,152,1,0,1,0,1,1,1,1,1,1,1,1,4, 1,161,8,1,11,1,12,1,162,1,1,4,1,166,8,1,11,1,12,1,167,1,1,1,1,1,2,1,2,1, 2,1,2,1,2,1,3,1,3,1,3,1,3,1,4,1,4,1,4,1,4,1,5,1,5,1,5,1,5,1,6,1,6,1,7,1, - 7,1,7,1,7,1,7,1,8,1,8,1,8,1,8,1,8,3,8,201,8,8,1,9,1,9,1,10,1,10,1,11,1, - 11,1,12,1,12,1,12,1,12,3,12,213,8,12,1,12,1,12,1,12,1,13,1,13,1,13,1,13, - 1,13,1,13,1,14,1,14,1,14,1,14,3,14,228,8,14,1,14,3,14,231,8,14,1,14,1,14, - 1,15,1,15,1,15,1,15,4,15,239,8,15,11,15,12,15,240,1,15,1,15,1,16,1,16,1, - 16,3,16,248,8,16,1,17,1,17,5,17,252,8,17,10,17,12,17,255,9,17,1,17,1,17, - 1,18,1,18,1,18,1,18,1,19,1,19,1,19,1,20,1,20,1,20,1,21,1,21,1,21,1,21,3, - 21,273,8,21,1,21,1,21,1,21,1,21,1,21,3,21,280,8,21,1,22,1,22,1,22,3,22, - 285,8,22,1,22,3,22,288,8,22,1,22,3,22,291,8,22,1,23,1,23,1,24,1,24,1,24, - 5,24,298,8,24,10,24,12,24,301,9,24,1,25,1,25,3,25,305,8,25,1,25,3,25,308, - 8,25,1,25,3,25,311,8,25,1,25,3,25,314,8,25,1,25,3,25,317,8,25,1,25,3,25, - 320,8,25,1,25,3,25,323,8,25,1,25,3,25,326,8,25,1,26,1,26,1,26,5,26,331, - 8,26,10,26,12,26,334,9,26,1,27,1,27,1,27,3,27,339,8,27,1,27,3,27,342,8, - 27,1,27,3,27,345,8,27,1,27,1,27,1,27,1,27,3,27,351,8,27,1,27,3,27,354,8, - 27,1,27,1,27,3,27,358,8,27,3,27,360,8,27,1,28,1,28,1,28,1,28,1,29,1,29, - 1,30,1,30,1,30,5,30,371,8,30,10,30,12,30,374,9,30,1,31,1,31,1,31,1,31,1, - 31,1,31,1,31,3,31,383,8,31,1,32,1,32,1,32,1,33,1,33,1,33,1,33,1,33,1,34, - 1,34,1,34,1,34,1,34,1,35,1,35,1,35,1,35,1,35,1,36,1,36,1,36,1,36,5,36,407, - 8,36,10,36,12,36,410,9,36,1,36,3,36,413,8,36,1,36,3,36,416,8,36,1,37,1, - 37,1,37,1,38,1,38,1,38,1,38,1,38,1,38,1,38,3,38,428,8,38,1,39,1,39,1,39, - 3,39,433,8,39,1,39,1,39,1,40,1,40,1,40,5,40,440,8,40,10,40,12,40,443,9, - 40,1,41,1,41,3,41,447,8,41,1,42,1,42,1,42,1,42,3,42,453,8,42,1,42,1,42, + 7,1,7,1,7,1,7,3,7,196,8,7,1,8,1,8,1,8,1,8,1,8,3,8,203,8,8,1,9,1,9,1,10, + 1,10,1,11,1,11,1,12,1,12,1,12,1,12,3,12,215,8,12,1,12,1,12,1,12,1,13,1, + 13,1,13,1,13,1,13,1,13,1,14,1,14,1,14,1,14,3,14,230,8,14,1,14,3,14,233, + 8,14,1,14,1,14,1,15,1,15,1,15,1,15,4,15,241,8,15,11,15,12,15,242,1,15,1, + 15,1,16,1,16,1,16,3,16,250,8,16,1,17,1,17,5,17,254,8,17,10,17,12,17,257, + 9,17,1,17,1,17,1,18,1,18,1,18,1,18,1,19,1,19,1,19,1,20,1,20,1,20,1,21,1, + 21,1,21,1,21,3,21,275,8,21,1,21,1,21,1,21,1,21,1,21,3,21,282,8,21,1,22, + 1,22,1,22,3,22,287,8,22,1,22,3,22,290,8,22,1,22,3,22,293,8,22,1,23,1,23, + 1,24,1,24,1,24,5,24,300,8,24,10,24,12,24,303,9,24,1,25,1,25,3,25,307,8, + 25,1,25,3,25,310,8,25,1,25,3,25,313,8,25,1,25,3,25,316,8,25,1,25,3,25,319, + 8,25,1,25,3,25,322,8,25,1,25,3,25,325,8,25,1,25,3,25,328,8,25,1,26,1,26, + 1,26,5,26,333,8,26,10,26,12,26,336,9,26,1,27,1,27,1,27,3,27,341,8,27,1, + 27,3,27,344,8,27,1,27,3,27,347,8,27,1,27,1,27,1,27,1,27,3,27,353,8,27,1, + 27,3,27,356,8,27,1,27,1,27,3,27,360,8,27,3,27,362,8,27,1,28,1,28,1,28,1, + 28,1,29,1,29,1,30,1,30,1,30,5,30,373,8,30,10,30,12,30,376,9,30,1,31,1,31, + 1,31,1,31,1,31,1,31,1,31,3,31,385,8,31,1,32,1,32,1,32,1,33,1,33,1,33,1, + 33,1,33,1,34,1,34,1,34,1,34,1,34,1,35,1,35,1,35,1,35,1,35,1,36,1,36,1,36, + 1,36,5,36,409,8,36,10,36,12,36,412,9,36,1,36,3,36,415,8,36,1,36,3,36,418, + 8,36,1,37,1,37,1,37,1,38,1,38,1,38,1,38,1,38,1,38,1,38,3,38,430,8,38,1, + 39,1,39,1,39,3,39,435,8,39,1,39,1,39,1,40,1,40,1,40,5,40,442,8,40,10,40, + 12,40,445,9,40,1,41,1,41,3,41,449,8,41,1,42,1,42,1,42,1,42,3,42,455,8,42, 1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1, 42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42, - 1,42,1,42,1,42,1,42,1,42,1,42,1,42,5,42,493,8,42,10,42,12,42,496,9,42,1, - 43,1,43,1,43,1,43,1,43,1,43,1,43,3,43,505,8,43,1,44,1,44,1,44,1,44,1,44, - 3,44,512,8,44,1,45,1,45,1,45,3,45,517,8,45,1,46,1,46,1,46,1,46,1,46,5,46, - 524,8,46,10,46,12,46,527,9,46,3,46,529,8,46,1,46,1,46,1,46,1,46,3,46,535, - 8,46,1,46,1,46,3,46,539,8,46,1,47,1,47,3,47,543,8,47,1,48,1,48,1,48,5,48, - 548,8,48,10,48,12,48,551,9,48,1,49,1,49,1,50,1,50,1,51,1,51,1,52,1,52,1, - 53,1,53,1,54,1,54,1,55,1,55,1,56,1,56,1,56,1,56,1,56,1,56,1,56,1,56,1,56, - 1,56,3,56,577,8,56,1,57,1,57,1,57,1,57,1,57,1,57,3,57,585,8,57,1,57,5,119, - 125,134,140,146,1,84,58,0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34, - 36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82, - 84,86,88,90,92,94,96,98,100,102,104,106,108,110,112,114,0,22,2,0,97,97, - 100,101,1,0,100,101,2,0,9,15,97,99,2,0,29,29,96,96,7,0,4,4,8,10,12,18,20, - 20,26,26,30,38,97,98,2,0,6,6,45,45,3,0,29,29,36,36,46,47,3,0,6,6,45,45, - 48,48,1,0,50,53,2,0,5,5,54,56,1,0,10,11,1,0,58,59,2,0,9,9,12,12,1,0,13, - 14,2,0,37,38,65,67,2,0,37,38,68,69,2,0,33,33,70,70,2,0,31,32,71,72,1,0, - 31,32,1,0,95,96,1,0,73,80,1,0,81,88,617,0,119,1,0,0,0,2,156,1,0,0,0,4,171, - 1,0,0,0,6,176,1,0,0,0,8,180,1,0,0,0,10,184,1,0,0,0,12,188,1,0,0,0,14,190, - 1,0,0,0,16,195,1,0,0,0,18,202,1,0,0,0,20,204,1,0,0,0,22,206,1,0,0,0,24, - 208,1,0,0,0,26,217,1,0,0,0,28,223,1,0,0,0,30,234,1,0,0,0,32,244,1,0,0,0, - 34,249,1,0,0,0,36,258,1,0,0,0,38,262,1,0,0,0,40,265,1,0,0,0,42,279,1,0, - 0,0,44,281,1,0,0,0,46,292,1,0,0,0,48,294,1,0,0,0,50,302,1,0,0,0,52,327, - 1,0,0,0,54,359,1,0,0,0,56,361,1,0,0,0,58,365,1,0,0,0,60,367,1,0,0,0,62, - 382,1,0,0,0,64,384,1,0,0,0,66,387,1,0,0,0,68,392,1,0,0,0,70,397,1,0,0,0, - 72,402,1,0,0,0,74,417,1,0,0,0,76,427,1,0,0,0,78,429,1,0,0,0,80,436,1,0, - 0,0,82,446,1,0,0,0,84,452,1,0,0,0,86,504,1,0,0,0,88,511,1,0,0,0,90,513, - 1,0,0,0,92,538,1,0,0,0,94,540,1,0,0,0,96,544,1,0,0,0,98,552,1,0,0,0,100, - 554,1,0,0,0,102,556,1,0,0,0,104,558,1,0,0,0,106,560,1,0,0,0,108,562,1,0, - 0,0,110,564,1,0,0,0,112,576,1,0,0,0,114,584,1,0,0,0,116,118,3,16,8,0,117, - 116,1,0,0,0,118,121,1,0,0,0,119,120,1,0,0,0,119,117,1,0,0,0,120,125,1,0, - 0,0,121,119,1,0,0,0,122,124,3,2,1,0,123,122,1,0,0,0,124,127,1,0,0,0,125, - 126,1,0,0,0,125,123,1,0,0,0,126,129,1,0,0,0,127,125,1,0,0,0,128,130,3,14, - 7,0,129,128,1,0,0,0,129,130,1,0,0,0,130,134,1,0,0,0,131,133,3,24,12,0,132, - 131,1,0,0,0,133,136,1,0,0,0,134,135,1,0,0,0,134,132,1,0,0,0,135,140,1,0, - 0,0,136,134,1,0,0,0,137,139,3,74,37,0,138,137,1,0,0,0,139,142,1,0,0,0,140, - 141,1,0,0,0,140,138,1,0,0,0,141,146,1,0,0,0,142,140,1,0,0,0,143,145,3,26, - 13,0,144,143,1,0,0,0,145,148,1,0,0,0,146,147,1,0,0,0,146,144,1,0,0,0,147, - 150,1,0,0,0,148,146,1,0,0,0,149,151,3,28,14,0,150,149,1,0,0,0,151,152,1, - 0,0,0,152,150,1,0,0,0,152,153,1,0,0,0,153,154,1,0,0,0,154,155,5,0,0,1,155, - 1,1,0,0,0,156,157,5,1,0,0,157,158,3,20,10,0,158,160,5,2,0,0,159,161,3,4, - 2,0,160,159,1,0,0,0,161,162,1,0,0,0,162,160,1,0,0,0,162,163,1,0,0,0,163, - 165,1,0,0,0,164,166,3,6,3,0,165,164,1,0,0,0,166,167,1,0,0,0,167,165,1,0, - 0,0,167,168,1,0,0,0,168,169,1,0,0,0,169,170,5,3,0,0,170,3,1,0,0,0,171,172, - 5,4,0,0,172,173,5,97,0,0,173,174,5,5,0,0,174,175,3,20,10,0,175,5,1,0,0, - 0,176,177,3,8,4,0,177,178,5,6,0,0,178,179,3,10,5,0,179,7,1,0,0,0,180,181, - 5,97,0,0,181,182,5,7,0,0,182,183,3,12,6,0,183,9,1,0,0,0,184,185,5,97,0, - 0,185,186,5,7,0,0,186,187,3,12,6,0,187,11,1,0,0,0,188,189,7,0,0,0,189,13, - 1,0,0,0,190,191,5,8,0,0,191,192,3,20,10,0,192,193,5,5,0,0,193,194,3,22, - 11,0,194,15,1,0,0,0,195,196,5,105,0,0,196,197,3,60,30,0,197,200,5,5,0,0, - 198,201,3,112,56,0,199,201,3,18,9,0,200,198,1,0,0,0,200,199,1,0,0,0,200, - 201,1,0,0,0,201,17,1,0,0,0,202,203,5,102,0,0,203,19,1,0,0,0,204,205,7,1, - 0,0,205,21,1,0,0,0,206,207,7,2,0,0,207,23,1,0,0,0,208,209,5,16,0,0,209, - 212,3,20,10,0,210,211,5,17,0,0,211,213,3,22,11,0,212,210,1,0,0,0,212,213, - 1,0,0,0,213,214,1,0,0,0,214,215,5,9,0,0,215,216,3,108,54,0,216,25,1,0,0, - 0,217,218,5,18,0,0,218,219,5,97,0,0,219,220,5,5,0,0,220,221,3,84,42,0,221, - 222,5,19,0,0,222,27,1,0,0,0,223,224,5,20,0,0,224,225,5,97,0,0,225,227,3, - 30,15,0,226,228,3,38,19,0,227,226,1,0,0,0,227,228,1,0,0,0,228,230,1,0,0, - 0,229,231,3,36,18,0,230,229,1,0,0,0,230,231,1,0,0,0,231,232,1,0,0,0,232, - 233,3,34,17,0,233,29,1,0,0,0,234,235,5,21,0,0,235,238,3,32,16,0,236,237, - 5,22,0,0,237,239,3,32,16,0,238,236,1,0,0,0,239,240,1,0,0,0,240,238,1,0, - 0,0,240,241,1,0,0,0,241,242,1,0,0,0,242,243,5,23,0,0,243,31,1,0,0,0,244, - 245,3,110,55,0,245,247,5,97,0,0,246,248,3,40,20,0,247,246,1,0,0,0,247,248, - 1,0,0,0,248,33,1,0,0,0,249,253,5,2,0,0,250,252,3,42,21,0,251,250,1,0,0, - 0,252,255,1,0,0,0,253,251,1,0,0,0,253,254,1,0,0,0,254,256,1,0,0,0,255,253, - 1,0,0,0,256,257,5,3,0,0,257,35,1,0,0,0,258,259,5,24,0,0,259,260,3,106,53, - 0,260,261,5,25,0,0,261,37,1,0,0,0,262,263,5,26,0,0,263,264,5,97,0,0,264, - 39,1,0,0,0,265,266,5,7,0,0,266,267,3,22,11,0,267,41,1,0,0,0,268,269,3,60, - 30,0,269,270,5,27,0,0,270,272,3,60,30,0,271,273,3,46,23,0,272,271,1,0,0, - 0,272,273,1,0,0,0,273,274,1,0,0,0,274,275,5,19,0,0,275,280,1,0,0,0,276, - 277,3,44,22,0,277,278,5,19,0,0,278,280,1,0,0,0,279,268,1,0,0,0,279,276, - 1,0,0,0,280,43,1,0,0,0,281,284,3,48,24,0,282,283,5,27,0,0,283,285,3,52, - 26,0,284,282,1,0,0,0,284,285,1,0,0,0,285,287,1,0,0,0,286,288,3,72,36,0, - 287,286,1,0,0,0,287,288,1,0,0,0,288,290,1,0,0,0,289,291,3,46,23,0,290,289, - 1,0,0,0,290,291,1,0,0,0,291,45,1,0,0,0,292,293,5,101,0,0,293,47,1,0,0,0, - 294,299,3,50,25,0,295,296,5,22,0,0,296,298,3,50,25,0,297,295,1,0,0,0,298, - 301,1,0,0,0,299,297,1,0,0,0,299,300,1,0,0,0,300,49,1,0,0,0,301,299,1,0, - 0,0,302,304,3,60,30,0,303,305,3,40,20,0,304,303,1,0,0,0,304,305,1,0,0,0, - 305,307,1,0,0,0,306,308,3,56,28,0,307,306,1,0,0,0,307,308,1,0,0,0,308,310, - 1,0,0,0,309,311,3,62,31,0,310,309,1,0,0,0,310,311,1,0,0,0,311,313,1,0,0, - 0,312,314,3,102,51,0,313,312,1,0,0,0,313,314,1,0,0,0,314,316,1,0,0,0,315, - 317,3,64,32,0,316,315,1,0,0,0,316,317,1,0,0,0,317,319,1,0,0,0,318,320,3, - 66,33,0,319,318,1,0,0,0,319,320,1,0,0,0,320,322,1,0,0,0,321,323,3,68,34, - 0,322,321,1,0,0,0,322,323,1,0,0,0,323,325,1,0,0,0,324,326,3,70,35,0,325, - 324,1,0,0,0,325,326,1,0,0,0,326,51,1,0,0,0,327,332,3,54,27,0,328,329,5, - 22,0,0,329,331,3,54,27,0,330,328,1,0,0,0,331,334,1,0,0,0,332,330,1,0,0, - 0,332,333,1,0,0,0,333,53,1,0,0,0,334,332,1,0,0,0,335,338,3,60,30,0,336, - 337,5,5,0,0,337,339,3,76,38,0,338,336,1,0,0,0,338,339,1,0,0,0,339,341,1, - 0,0,0,340,342,3,64,32,0,341,340,1,0,0,0,341,342,1,0,0,0,342,344,1,0,0,0, - 343,345,3,104,52,0,344,343,1,0,0,0,344,345,1,0,0,0,345,360,1,0,0,0,346, - 347,5,21,0,0,347,348,3,84,42,0,348,350,5,23,0,0,349,351,3,64,32,0,350,349, - 1,0,0,0,350,351,1,0,0,0,351,353,1,0,0,0,352,354,3,104,52,0,353,352,1,0, - 0,0,353,354,1,0,0,0,354,360,1,0,0,0,355,357,3,78,39,0,356,358,3,64,32,0, - 357,356,1,0,0,0,357,358,1,0,0,0,358,360,1,0,0,0,359,335,1,0,0,0,359,346, - 1,0,0,0,359,355,1,0,0,0,360,55,1,0,0,0,361,362,5,96,0,0,362,363,5,28,0, - 0,363,364,3,58,29,0,364,57,1,0,0,0,365,366,7,3,0,0,366,59,1,0,0,0,367,372, - 7,4,0,0,368,369,5,39,0,0,369,371,7,4,0,0,370,368,1,0,0,0,371,374,1,0,0, - 0,372,370,1,0,0,0,372,373,1,0,0,0,373,61,1,0,0,0,374,372,1,0,0,0,375,376, - 5,40,0,0,376,377,5,21,0,0,377,378,3,84,42,0,378,379,5,23,0,0,379,383,1, - 0,0,0,380,381,5,40,0,0,381,383,5,101,0,0,382,375,1,0,0,0,382,380,1,0,0, - 0,383,63,1,0,0,0,384,385,5,9,0,0,385,386,3,22,11,0,386,65,1,0,0,0,387,388, - 5,34,0,0,388,389,5,21,0,0,389,390,3,84,42,0,390,391,5,23,0,0,391,67,1,0, - 0,0,392,393,5,35,0,0,393,394,5,21,0,0,394,395,3,84,42,0,395,396,5,23,0, - 0,396,69,1,0,0,0,397,398,5,41,0,0,398,399,5,21,0,0,399,400,3,84,42,0,400, - 401,5,23,0,0,401,71,1,0,0,0,402,415,5,42,0,0,403,408,3,78,39,0,404,405, - 5,22,0,0,405,407,3,78,39,0,406,404,1,0,0,0,407,410,1,0,0,0,408,406,1,0, - 0,0,408,409,1,0,0,0,409,412,1,0,0,0,410,408,1,0,0,0,411,413,3,34,17,0,412, - 411,1,0,0,0,412,413,1,0,0,0,413,416,1,0,0,0,414,416,3,34,17,0,415,403,1, - 0,0,0,415,414,1,0,0,0,416,73,1,0,0,0,417,418,5,30,0,0,418,419,3,20,10,0, - 419,75,1,0,0,0,420,428,3,112,56,0,421,428,3,60,30,0,422,428,3,78,39,0,423, - 424,5,21,0,0,424,425,3,84,42,0,425,426,5,23,0,0,426,428,1,0,0,0,427,420, - 1,0,0,0,427,421,1,0,0,0,427,422,1,0,0,0,427,423,1,0,0,0,428,77,1,0,0,0, - 429,430,3,22,11,0,430,432,5,21,0,0,431,433,3,80,40,0,432,431,1,0,0,0,432, - 433,1,0,0,0,433,434,1,0,0,0,434,435,5,23,0,0,435,79,1,0,0,0,436,441,3,82, - 41,0,437,438,5,22,0,0,438,440,3,82,41,0,439,437,1,0,0,0,440,443,1,0,0,0, - 441,439,1,0,0,0,441,442,1,0,0,0,442,81,1,0,0,0,443,441,1,0,0,0,444,447, - 3,112,56,0,445,447,5,97,0,0,446,444,1,0,0,0,446,445,1,0,0,0,447,83,1,0, - 0,0,448,449,6,42,-1,0,449,453,3,86,43,0,450,451,7,5,0,0,451,453,3,84,42, - 11,452,448,1,0,0,0,452,450,1,0,0,0,453,494,1,0,0,0,454,455,10,10,0,0,455, - 456,7,6,0,0,456,493,3,84,42,11,457,458,10,9,0,0,458,459,7,7,0,0,459,493, - 3,84,42,10,460,461,10,7,0,0,461,462,5,49,0,0,462,493,3,84,42,8,463,464, - 10,6,0,0,464,465,7,8,0,0,465,493,3,84,42,7,466,467,10,5,0,0,467,468,7,9, - 0,0,468,493,3,84,42,6,469,470,10,4,0,0,470,471,7,10,0,0,471,493,3,84,42, - 5,472,473,10,3,0,0,473,474,5,57,0,0,474,493,3,84,42,4,475,476,10,2,0,0, - 476,477,7,11,0,0,477,493,3,84,42,3,478,479,10,1,0,0,479,480,5,60,0,0,480, - 493,3,84,42,2,481,482,10,13,0,0,482,483,5,39,0,0,483,493,3,88,44,0,484, - 485,10,12,0,0,485,486,5,43,0,0,486,487,3,84,42,0,487,488,5,44,0,0,488,493, - 1,0,0,0,489,490,10,8,0,0,490,491,7,12,0,0,491,493,3,98,49,0,492,454,1,0, - 0,0,492,457,1,0,0,0,492,460,1,0,0,0,492,463,1,0,0,0,492,466,1,0,0,0,492, - 469,1,0,0,0,492,472,1,0,0,0,492,475,1,0,0,0,492,478,1,0,0,0,492,481,1,0, - 0,0,492,484,1,0,0,0,492,489,1,0,0,0,493,496,1,0,0,0,494,492,1,0,0,0,494, - 495,1,0,0,0,495,85,1,0,0,0,496,494,1,0,0,0,497,505,3,88,44,0,498,505,3, - 112,56,0,499,505,3,90,45,0,500,501,5,21,0,0,501,502,3,84,42,0,502,503,5, - 23,0,0,503,505,1,0,0,0,504,497,1,0,0,0,504,498,1,0,0,0,504,499,1,0,0,0, - 504,500,1,0,0,0,505,87,1,0,0,0,506,512,3,92,46,0,507,512,3,22,11,0,508, - 512,5,61,0,0,509,512,5,62,0,0,510,512,5,63,0,0,511,506,1,0,0,0,511,507, - 1,0,0,0,511,508,1,0,0,0,511,509,1,0,0,0,511,510,1,0,0,0,512,89,1,0,0,0, - 513,516,5,64,0,0,514,517,3,22,11,0,515,517,5,100,0,0,516,514,1,0,0,0,516, - 515,1,0,0,0,517,91,1,0,0,0,518,519,5,15,0,0,519,528,5,21,0,0,520,525,3, - 94,47,0,521,522,5,22,0,0,522,524,3,94,47,0,523,521,1,0,0,0,524,527,1,0, - 0,0,525,523,1,0,0,0,525,526,1,0,0,0,526,529,1,0,0,0,527,525,1,0,0,0,528, - 520,1,0,0,0,528,529,1,0,0,0,529,530,1,0,0,0,530,539,5,23,0,0,531,532,3, - 60,30,0,532,534,5,21,0,0,533,535,3,96,48,0,534,533,1,0,0,0,534,535,1,0, - 0,0,535,536,1,0,0,0,536,537,5,23,0,0,537,539,1,0,0,0,538,518,1,0,0,0,538, - 531,1,0,0,0,539,93,1,0,0,0,540,542,3,84,42,0,541,543,7,13,0,0,542,541,1, - 0,0,0,542,543,1,0,0,0,543,95,1,0,0,0,544,549,3,84,42,0,545,546,5,22,0,0, - 546,548,3,84,42,0,547,545,1,0,0,0,548,551,1,0,0,0,549,547,1,0,0,0,549,550, - 1,0,0,0,550,97,1,0,0,0,551,549,1,0,0,0,552,553,3,60,30,0,553,99,1,0,0,0, - 554,555,5,97,0,0,555,101,1,0,0,0,556,557,7,14,0,0,557,103,1,0,0,0,558,559, - 7,15,0,0,559,105,1,0,0,0,560,561,7,16,0,0,561,107,1,0,0,0,562,563,7,17, - 0,0,563,109,1,0,0,0,564,565,7,18,0,0,565,111,1,0,0,0,566,577,5,89,0,0,567, - 577,5,90,0,0,568,577,3,114,57,0,569,577,5,94,0,0,570,577,7,19,0,0,571,577, - 5,91,0,0,572,577,5,92,0,0,573,577,5,93,0,0,574,577,5,100,0,0,575,577,5, - 101,0,0,576,566,1,0,0,0,576,567,1,0,0,0,576,568,1,0,0,0,576,569,1,0,0,0, - 576,570,1,0,0,0,576,571,1,0,0,0,576,572,1,0,0,0,576,573,1,0,0,0,576,574, - 1,0,0,0,576,575,1,0,0,0,577,113,1,0,0,0,578,579,7,19,0,0,579,585,7,20,0, - 0,580,581,7,19,0,0,581,585,7,21,0,0,582,583,7,19,0,0,583,585,5,100,0,0, - 584,578,1,0,0,0,584,580,1,0,0,0,584,582,1,0,0,0,585,115,1,0,0,0,61,119, - 125,129,134,140,146,152,162,167,200,212,227,230,240,247,253,272,279,284, - 287,290,299,304,307,310,313,316,319,322,325,332,338,341,344,350,353,357, - 359,372,382,408,412,415,427,432,441,446,452,492,494,504,511,516,525,528, - 534,538,542,549,576,584]; + 1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,5,42,495,8,42,10,42,12,42, + 498,9,42,1,43,1,43,1,43,1,43,1,43,1,43,1,43,3,43,507,8,43,1,44,1,44,1,44, + 1,44,1,44,3,44,514,8,44,1,45,1,45,1,45,3,45,519,8,45,1,46,1,46,1,46,1,46, + 1,46,5,46,526,8,46,10,46,12,46,529,9,46,3,46,531,8,46,1,46,1,46,1,46,1, + 46,3,46,537,8,46,1,46,1,46,3,46,541,8,46,1,47,1,47,3,47,545,8,47,1,48,1, + 48,1,48,5,48,550,8,48,10,48,12,48,553,9,48,1,49,1,49,1,50,1,50,1,51,1,51, + 1,52,1,52,1,53,1,53,1,54,1,54,1,55,1,55,1,56,1,56,1,56,1,56,1,56,1,56,1, + 56,1,56,1,56,1,56,3,56,579,8,56,1,57,1,57,1,57,1,57,1,57,1,57,3,57,587, + 8,57,1,57,5,119,125,134,140,146,1,84,58,0,2,4,6,8,10,12,14,16,18,20,22, + 24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70, + 72,74,76,78,80,82,84,86,88,90,92,94,96,98,100,102,104,106,108,110,112,114, + 0,22,2,0,97,97,100,101,1,0,100,101,2,0,9,15,97,99,2,0,29,29,96,96,7,0,4, + 4,8,10,12,18,20,20,26,26,30,38,97,98,2,0,6,6,45,45,3,0,29,29,36,36,46,47, + 3,0,6,6,45,45,48,48,1,0,50,53,2,0,5,5,54,56,1,0,10,11,1,0,58,59,2,0,9,9, + 12,12,1,0,13,14,2,0,37,38,65,67,2,0,37,38,68,69,2,0,33,33,70,70,2,0,31, + 32,71,72,1,0,31,32,1,0,95,96,1,0,73,80,1,0,81,88,620,0,119,1,0,0,0,2,156, + 1,0,0,0,4,171,1,0,0,0,6,176,1,0,0,0,8,180,1,0,0,0,10,184,1,0,0,0,12,188, + 1,0,0,0,14,190,1,0,0,0,16,197,1,0,0,0,18,204,1,0,0,0,20,206,1,0,0,0,22, + 208,1,0,0,0,24,210,1,0,0,0,26,219,1,0,0,0,28,225,1,0,0,0,30,236,1,0,0,0, + 32,246,1,0,0,0,34,251,1,0,0,0,36,260,1,0,0,0,38,264,1,0,0,0,40,267,1,0, + 0,0,42,281,1,0,0,0,44,283,1,0,0,0,46,294,1,0,0,0,48,296,1,0,0,0,50,304, + 1,0,0,0,52,329,1,0,0,0,54,361,1,0,0,0,56,363,1,0,0,0,58,367,1,0,0,0,60, + 369,1,0,0,0,62,384,1,0,0,0,64,386,1,0,0,0,66,389,1,0,0,0,68,394,1,0,0,0, + 70,399,1,0,0,0,72,404,1,0,0,0,74,419,1,0,0,0,76,429,1,0,0,0,78,431,1,0, + 0,0,80,438,1,0,0,0,82,448,1,0,0,0,84,454,1,0,0,0,86,506,1,0,0,0,88,513, + 1,0,0,0,90,515,1,0,0,0,92,540,1,0,0,0,94,542,1,0,0,0,96,546,1,0,0,0,98, + 554,1,0,0,0,100,556,1,0,0,0,102,558,1,0,0,0,104,560,1,0,0,0,106,562,1,0, + 0,0,108,564,1,0,0,0,110,566,1,0,0,0,112,578,1,0,0,0,114,586,1,0,0,0,116, + 118,3,16,8,0,117,116,1,0,0,0,118,121,1,0,0,0,119,120,1,0,0,0,119,117,1, + 0,0,0,120,125,1,0,0,0,121,119,1,0,0,0,122,124,3,2,1,0,123,122,1,0,0,0,124, + 127,1,0,0,0,125,126,1,0,0,0,125,123,1,0,0,0,126,129,1,0,0,0,127,125,1,0, + 0,0,128,130,3,14,7,0,129,128,1,0,0,0,129,130,1,0,0,0,130,134,1,0,0,0,131, + 133,3,24,12,0,132,131,1,0,0,0,133,136,1,0,0,0,134,135,1,0,0,0,134,132,1, + 0,0,0,135,140,1,0,0,0,136,134,1,0,0,0,137,139,3,74,37,0,138,137,1,0,0,0, + 139,142,1,0,0,0,140,141,1,0,0,0,140,138,1,0,0,0,141,146,1,0,0,0,142,140, + 1,0,0,0,143,145,3,26,13,0,144,143,1,0,0,0,145,148,1,0,0,0,146,147,1,0,0, + 0,146,144,1,0,0,0,147,150,1,0,0,0,148,146,1,0,0,0,149,151,3,28,14,0,150, + 149,1,0,0,0,151,152,1,0,0,0,152,150,1,0,0,0,152,153,1,0,0,0,153,154,1,0, + 0,0,154,155,5,0,0,1,155,1,1,0,0,0,156,157,5,1,0,0,157,158,3,20,10,0,158, + 160,5,2,0,0,159,161,3,4,2,0,160,159,1,0,0,0,161,162,1,0,0,0,162,160,1,0, + 0,0,162,163,1,0,0,0,163,165,1,0,0,0,164,166,3,6,3,0,165,164,1,0,0,0,166, + 167,1,0,0,0,167,165,1,0,0,0,167,168,1,0,0,0,168,169,1,0,0,0,169,170,5,3, + 0,0,170,3,1,0,0,0,171,172,5,4,0,0,172,173,5,97,0,0,173,174,5,5,0,0,174, + 175,3,20,10,0,175,5,1,0,0,0,176,177,3,8,4,0,177,178,5,6,0,0,178,179,3,10, + 5,0,179,7,1,0,0,0,180,181,5,97,0,0,181,182,5,7,0,0,182,183,3,12,6,0,183, + 9,1,0,0,0,184,185,5,97,0,0,185,186,5,7,0,0,186,187,3,12,6,0,187,11,1,0, + 0,0,188,189,7,0,0,0,189,13,1,0,0,0,190,191,5,8,0,0,191,192,3,20,10,0,192, + 195,5,5,0,0,193,196,3,22,11,0,194,196,5,101,0,0,195,193,1,0,0,0,195,194, + 1,0,0,0,196,15,1,0,0,0,197,198,5,105,0,0,198,199,3,60,30,0,199,202,5,5, + 0,0,200,203,3,112,56,0,201,203,3,18,9,0,202,200,1,0,0,0,202,201,1,0,0,0, + 202,203,1,0,0,0,203,17,1,0,0,0,204,205,5,102,0,0,205,19,1,0,0,0,206,207, + 7,1,0,0,207,21,1,0,0,0,208,209,7,2,0,0,209,23,1,0,0,0,210,211,5,16,0,0, + 211,214,3,20,10,0,212,213,5,17,0,0,213,215,3,22,11,0,214,212,1,0,0,0,214, + 215,1,0,0,0,215,216,1,0,0,0,216,217,5,9,0,0,217,218,3,108,54,0,218,25,1, + 0,0,0,219,220,5,18,0,0,220,221,5,97,0,0,221,222,5,5,0,0,222,223,3,84,42, + 0,223,224,5,19,0,0,224,27,1,0,0,0,225,226,5,20,0,0,226,227,5,97,0,0,227, + 229,3,30,15,0,228,230,3,38,19,0,229,228,1,0,0,0,229,230,1,0,0,0,230,232, + 1,0,0,0,231,233,3,36,18,0,232,231,1,0,0,0,232,233,1,0,0,0,233,234,1,0,0, + 0,234,235,3,34,17,0,235,29,1,0,0,0,236,237,5,21,0,0,237,240,3,32,16,0,238, + 239,5,22,0,0,239,241,3,32,16,0,240,238,1,0,0,0,241,242,1,0,0,0,242,240, + 1,0,0,0,242,243,1,0,0,0,243,244,1,0,0,0,244,245,5,23,0,0,245,31,1,0,0,0, + 246,247,3,110,55,0,247,249,5,97,0,0,248,250,3,40,20,0,249,248,1,0,0,0,249, + 250,1,0,0,0,250,33,1,0,0,0,251,255,5,2,0,0,252,254,3,42,21,0,253,252,1, + 0,0,0,254,257,1,0,0,0,255,253,1,0,0,0,255,256,1,0,0,0,256,258,1,0,0,0,257, + 255,1,0,0,0,258,259,5,3,0,0,259,35,1,0,0,0,260,261,5,24,0,0,261,262,3,106, + 53,0,262,263,5,25,0,0,263,37,1,0,0,0,264,265,5,26,0,0,265,266,5,97,0,0, + 266,39,1,0,0,0,267,268,5,7,0,0,268,269,3,22,11,0,269,41,1,0,0,0,270,271, + 3,60,30,0,271,272,5,27,0,0,272,274,3,60,30,0,273,275,3,46,23,0,274,273, + 1,0,0,0,274,275,1,0,0,0,275,276,1,0,0,0,276,277,5,19,0,0,277,282,1,0,0, + 0,278,279,3,44,22,0,279,280,5,19,0,0,280,282,1,0,0,0,281,270,1,0,0,0,281, + 278,1,0,0,0,282,43,1,0,0,0,283,286,3,48,24,0,284,285,5,27,0,0,285,287,3, + 52,26,0,286,284,1,0,0,0,286,287,1,0,0,0,287,289,1,0,0,0,288,290,3,72,36, + 0,289,288,1,0,0,0,289,290,1,0,0,0,290,292,1,0,0,0,291,293,3,46,23,0,292, + 291,1,0,0,0,292,293,1,0,0,0,293,45,1,0,0,0,294,295,5,101,0,0,295,47,1,0, + 0,0,296,301,3,50,25,0,297,298,5,22,0,0,298,300,3,50,25,0,299,297,1,0,0, + 0,300,303,1,0,0,0,301,299,1,0,0,0,301,302,1,0,0,0,302,49,1,0,0,0,303,301, + 1,0,0,0,304,306,3,60,30,0,305,307,3,40,20,0,306,305,1,0,0,0,306,307,1,0, + 0,0,307,309,1,0,0,0,308,310,3,56,28,0,309,308,1,0,0,0,309,310,1,0,0,0,310, + 312,1,0,0,0,311,313,3,62,31,0,312,311,1,0,0,0,312,313,1,0,0,0,313,315,1, + 0,0,0,314,316,3,102,51,0,315,314,1,0,0,0,315,316,1,0,0,0,316,318,1,0,0, + 0,317,319,3,64,32,0,318,317,1,0,0,0,318,319,1,0,0,0,319,321,1,0,0,0,320, + 322,3,66,33,0,321,320,1,0,0,0,321,322,1,0,0,0,322,324,1,0,0,0,323,325,3, + 68,34,0,324,323,1,0,0,0,324,325,1,0,0,0,325,327,1,0,0,0,326,328,3,70,35, + 0,327,326,1,0,0,0,327,328,1,0,0,0,328,51,1,0,0,0,329,334,3,54,27,0,330, + 331,5,22,0,0,331,333,3,54,27,0,332,330,1,0,0,0,333,336,1,0,0,0,334,332, + 1,0,0,0,334,335,1,0,0,0,335,53,1,0,0,0,336,334,1,0,0,0,337,340,3,60,30, + 0,338,339,5,5,0,0,339,341,3,76,38,0,340,338,1,0,0,0,340,341,1,0,0,0,341, + 343,1,0,0,0,342,344,3,64,32,0,343,342,1,0,0,0,343,344,1,0,0,0,344,346,1, + 0,0,0,345,347,3,104,52,0,346,345,1,0,0,0,346,347,1,0,0,0,347,362,1,0,0, + 0,348,349,5,21,0,0,349,350,3,84,42,0,350,352,5,23,0,0,351,353,3,64,32,0, + 352,351,1,0,0,0,352,353,1,0,0,0,353,355,1,0,0,0,354,356,3,104,52,0,355, + 354,1,0,0,0,355,356,1,0,0,0,356,362,1,0,0,0,357,359,3,78,39,0,358,360,3, + 64,32,0,359,358,1,0,0,0,359,360,1,0,0,0,360,362,1,0,0,0,361,337,1,0,0,0, + 361,348,1,0,0,0,361,357,1,0,0,0,362,55,1,0,0,0,363,364,5,96,0,0,364,365, + 5,28,0,0,365,366,3,58,29,0,366,57,1,0,0,0,367,368,7,3,0,0,368,59,1,0,0, + 0,369,374,7,4,0,0,370,371,5,39,0,0,371,373,7,4,0,0,372,370,1,0,0,0,373, + 376,1,0,0,0,374,372,1,0,0,0,374,375,1,0,0,0,375,61,1,0,0,0,376,374,1,0, + 0,0,377,378,5,40,0,0,378,379,5,21,0,0,379,380,3,84,42,0,380,381,5,23,0, + 0,381,385,1,0,0,0,382,383,5,40,0,0,383,385,5,101,0,0,384,377,1,0,0,0,384, + 382,1,0,0,0,385,63,1,0,0,0,386,387,5,9,0,0,387,388,3,22,11,0,388,65,1,0, + 0,0,389,390,5,34,0,0,390,391,5,21,0,0,391,392,3,84,42,0,392,393,5,23,0, + 0,393,67,1,0,0,0,394,395,5,35,0,0,395,396,5,21,0,0,396,397,3,84,42,0,397, + 398,5,23,0,0,398,69,1,0,0,0,399,400,5,41,0,0,400,401,5,21,0,0,401,402,3, + 84,42,0,402,403,5,23,0,0,403,71,1,0,0,0,404,417,5,42,0,0,405,410,3,78,39, + 0,406,407,5,22,0,0,407,409,3,78,39,0,408,406,1,0,0,0,409,412,1,0,0,0,410, + 408,1,0,0,0,410,411,1,0,0,0,411,414,1,0,0,0,412,410,1,0,0,0,413,415,3,34, + 17,0,414,413,1,0,0,0,414,415,1,0,0,0,415,418,1,0,0,0,416,418,3,34,17,0, + 417,405,1,0,0,0,417,416,1,0,0,0,418,73,1,0,0,0,419,420,5,30,0,0,420,421, + 3,20,10,0,421,75,1,0,0,0,422,430,3,112,56,0,423,430,3,60,30,0,424,430,3, + 78,39,0,425,426,5,21,0,0,426,427,3,84,42,0,427,428,5,23,0,0,428,430,1,0, + 0,0,429,422,1,0,0,0,429,423,1,0,0,0,429,424,1,0,0,0,429,425,1,0,0,0,430, + 77,1,0,0,0,431,432,3,22,11,0,432,434,5,21,0,0,433,435,3,80,40,0,434,433, + 1,0,0,0,434,435,1,0,0,0,435,436,1,0,0,0,436,437,5,23,0,0,437,79,1,0,0,0, + 438,443,3,82,41,0,439,440,5,22,0,0,440,442,3,82,41,0,441,439,1,0,0,0,442, + 445,1,0,0,0,443,441,1,0,0,0,443,444,1,0,0,0,444,81,1,0,0,0,445,443,1,0, + 0,0,446,449,3,112,56,0,447,449,5,97,0,0,448,446,1,0,0,0,448,447,1,0,0,0, + 449,83,1,0,0,0,450,451,6,42,-1,0,451,455,3,86,43,0,452,453,7,5,0,0,453, + 455,3,84,42,11,454,450,1,0,0,0,454,452,1,0,0,0,455,496,1,0,0,0,456,457, + 10,10,0,0,457,458,7,6,0,0,458,495,3,84,42,11,459,460,10,9,0,0,460,461,7, + 7,0,0,461,495,3,84,42,10,462,463,10,7,0,0,463,464,5,49,0,0,464,495,3,84, + 42,8,465,466,10,6,0,0,466,467,7,8,0,0,467,495,3,84,42,7,468,469,10,5,0, + 0,469,470,7,9,0,0,470,495,3,84,42,6,471,472,10,4,0,0,472,473,7,10,0,0,473, + 495,3,84,42,5,474,475,10,3,0,0,475,476,5,57,0,0,476,495,3,84,42,4,477,478, + 10,2,0,0,478,479,7,11,0,0,479,495,3,84,42,3,480,481,10,1,0,0,481,482,5, + 60,0,0,482,495,3,84,42,2,483,484,10,13,0,0,484,485,5,39,0,0,485,495,3,88, + 44,0,486,487,10,12,0,0,487,488,5,43,0,0,488,489,3,84,42,0,489,490,5,44, + 0,0,490,495,1,0,0,0,491,492,10,8,0,0,492,493,7,12,0,0,493,495,3,98,49,0, + 494,456,1,0,0,0,494,459,1,0,0,0,494,462,1,0,0,0,494,465,1,0,0,0,494,468, + 1,0,0,0,494,471,1,0,0,0,494,474,1,0,0,0,494,477,1,0,0,0,494,480,1,0,0,0, + 494,483,1,0,0,0,494,486,1,0,0,0,494,491,1,0,0,0,495,498,1,0,0,0,496,494, + 1,0,0,0,496,497,1,0,0,0,497,85,1,0,0,0,498,496,1,0,0,0,499,507,3,88,44, + 0,500,507,3,112,56,0,501,507,3,90,45,0,502,503,5,21,0,0,503,504,3,84,42, + 0,504,505,5,23,0,0,505,507,1,0,0,0,506,499,1,0,0,0,506,500,1,0,0,0,506, + 501,1,0,0,0,506,502,1,0,0,0,507,87,1,0,0,0,508,514,3,92,46,0,509,514,3, + 22,11,0,510,514,5,61,0,0,511,514,5,62,0,0,512,514,5,63,0,0,513,508,1,0, + 0,0,513,509,1,0,0,0,513,510,1,0,0,0,513,511,1,0,0,0,513,512,1,0,0,0,514, + 89,1,0,0,0,515,518,5,64,0,0,516,519,3,22,11,0,517,519,5,100,0,0,518,516, + 1,0,0,0,518,517,1,0,0,0,519,91,1,0,0,0,520,521,5,15,0,0,521,530,5,21,0, + 0,522,527,3,94,47,0,523,524,5,22,0,0,524,526,3,94,47,0,525,523,1,0,0,0, + 526,529,1,0,0,0,527,525,1,0,0,0,527,528,1,0,0,0,528,531,1,0,0,0,529,527, + 1,0,0,0,530,522,1,0,0,0,530,531,1,0,0,0,531,532,1,0,0,0,532,541,5,23,0, + 0,533,534,3,60,30,0,534,536,5,21,0,0,535,537,3,96,48,0,536,535,1,0,0,0, + 536,537,1,0,0,0,537,538,1,0,0,0,538,539,5,23,0,0,539,541,1,0,0,0,540,520, + 1,0,0,0,540,533,1,0,0,0,541,93,1,0,0,0,542,544,3,84,42,0,543,545,7,13,0, + 0,544,543,1,0,0,0,544,545,1,0,0,0,545,95,1,0,0,0,546,551,3,84,42,0,547, + 548,5,22,0,0,548,550,3,84,42,0,549,547,1,0,0,0,550,553,1,0,0,0,551,549, + 1,0,0,0,551,552,1,0,0,0,552,97,1,0,0,0,553,551,1,0,0,0,554,555,3,60,30, + 0,555,99,1,0,0,0,556,557,5,97,0,0,557,101,1,0,0,0,558,559,7,14,0,0,559, + 103,1,0,0,0,560,561,7,15,0,0,561,105,1,0,0,0,562,563,7,16,0,0,563,107,1, + 0,0,0,564,565,7,17,0,0,565,109,1,0,0,0,566,567,7,18,0,0,567,111,1,0,0,0, + 568,579,5,89,0,0,569,579,5,90,0,0,570,579,3,114,57,0,571,579,5,94,0,0,572, + 579,7,19,0,0,573,579,5,91,0,0,574,579,5,92,0,0,575,579,5,93,0,0,576,579, + 5,100,0,0,577,579,5,101,0,0,578,568,1,0,0,0,578,569,1,0,0,0,578,570,1,0, + 0,0,578,571,1,0,0,0,578,572,1,0,0,0,578,573,1,0,0,0,578,574,1,0,0,0,578, + 575,1,0,0,0,578,576,1,0,0,0,578,577,1,0,0,0,579,113,1,0,0,0,580,581,7,19, + 0,0,581,587,7,20,0,0,582,583,7,19,0,0,583,587,7,21,0,0,584,585,7,19,0,0, + 585,587,5,100,0,0,586,580,1,0,0,0,586,582,1,0,0,0,586,584,1,0,0,0,587,115, + 1,0,0,0,62,119,125,129,134,140,146,152,162,167,195,202,214,229,232,242, + 249,255,274,281,286,289,292,301,306,309,312,315,318,321,324,327,334,340, + 343,346,352,355,359,361,374,384,410,414,417,429,434,443,448,454,494,496, + 506,513,518,527,530,536,540,544,551,578,586]; private static __ATN: ATN; public static get _ATN(): ATN { @@ -3931,6 +3957,9 @@ export class MapDeclarationContext extends ParserRuleContext { public identifier(): IdentifierContext { return this.getTypedRuleContext(IdentifierContext, 0) as IdentifierContext; } + public DOUBLE_QUOTED_STRING(): TerminalNode { + return this.getToken(FmlMappingParser.DOUBLE_QUOTED_STRING, 0); + } public get ruleIndex(): number { return FmlMappingParser.RULE_mapDeclaration; } diff --git a/helpers/fml_cross_version.ts b/helpers/fml_cross_version.ts new file mode 100644 index 00000000..db27fb23 --- /dev/null +++ b/helpers/fml_cross_version.ts @@ -0,0 +1,165 @@ +/** + * Cross-version canonical support for FML diagramming. + * + * FHIR cross-version maps reference structures using version-qualified + * canonical URLs of the form: + * + * http://hl7.org/fhir/./StructureDefinition/ + * + * The version segment (e.g. `4.3`, `5.0`) identifies the FHIR release + * that owns the StructureDefinition. To resolve such a structure against + * an existing per-version model catalogue (which is keyed on the plain + * `http://hl7.org/fhir/StructureDefinition/` canonical) the version + * segment must be parsed out and the URL normalised back to the + * version-neutral canonical form. + */ + +import type { StructureDeclaration, FhirVersion } from "./fml_models"; + +/** Re-export so existing importers from this module keep working. */ +export type { FhirVersion } from "./fml_models"; + +/** + * Mapping from `.` URL segment to FHIR release identifier. + * See https://www.hl7.org/fhir/versions.html#versioning. + */ +const VERSION_SEGMENT_TO_FHIR: Record = { + '1.0': 'DSTU2', + '3.0': 'STU3', + '4.0': 'R4', + '4.3': 'R4B', + '5.0': 'R5', + '6.0': 'R6', +}; + +/** + * Pattern matching `http(s)://hl7.org/fhir/./` where + * `` is captured so the URL can be rebuilt without the version + * segment. + */ +const CROSS_VERSION_URL_RE = + /^(https?:\/\/hl7\.org\/fhir)\/(\d+\.\d+)\/(.+)$/; + +/** + * Result of parsing a (possibly version-qualified) canonical URL. + */ +export interface ParsedCanonical { + /** + * The version-neutral canonical that should be used to look the + * structure up in a model catalogue. If the input URL did not contain + * a recognisable FHIR version segment this is identical to the input + * URL. + */ + canonical: string; + + /** + * The detected FHIR release, or `undefined` if the URL did not carry a + * recognisable version segment (plain canonical, logical model URL, + * non-hl7.org URL, ...). + */ + version?: FhirVersion; +} + +/** + * Parse a canonical URL and detect any embedded FHIR version segment. + * + * Examples: + * parseCanonicalVersion("http://hl7.org/fhir/4.3/StructureDefinition/Citation") + * => { canonical: "http://hl7.org/fhir/StructureDefinition/Citation", + * version: "R4B" } + * + * parseCanonicalVersion("http://hl7.org/fhir/StructureDefinition/Patient") + * => { canonical: "http://hl7.org/fhir/StructureDefinition/Patient", + * version: undefined } + * + * parseCanonicalVersion("http://example.org/fhir/StructureDefinition/MyLogical") + * => { canonical: "http://example.org/fhir/StructureDefinition/MyLogical", + * version: undefined } + */ +export function parseCanonicalVersion(url: string): ParsedCanonical { + if (!url) { + return { canonical: url }; + } + + const m = CROSS_VERSION_URL_RE.exec(url); + if (!m) { + return { canonical: url }; + } + + const [, prefix, segment, rest] = m; + const version = VERSION_SEGMENT_TO_FHIR[segment]; + if (!version) { + // hl7.org/fhir//... but `` is not a recognised release, so + // leave the URL untouched. + return { canonical: url }; + } + + return { + canonical: `${prefix}/${rest}`, + version, + }; +} + +/** + * Roles a `uses` declaration may take in an FML map. + */ +export type StructureRole = 'source' | 'queried' | 'target' | 'produced'; + +/** + * The auto-detected source/target FHIR model versions for an FML map. + * + * Each value is `undefined` when no `uses` declaration of that role + * carried a recognised version segment; callers should fall back to + * their global default (or a user override) in that case. + */ +export interface DetectedModelVersions { + /** Version of the first `uses ... as source` (or `as queried`) that has a version segment. */ + sourceModelVersion?: FhirVersion; + /** Version of the first `uses ... as target` (or `as produced`) that has a version segment. */ + targetModelVersion?: FhirVersion; +} + +/** + * Inspect a list of `uses` (structure) declarations and pick the + * source/target model versions to use when diagramming. + * + * Per the plan: + * - `sourceModelVersion` = version of the first `uses ... as source` + * declaration with a version segment. + * - `targetModelVersion` = same rule for `uses ... as target`. + * - `queried` follows `source`, `produced` follows `target` (only used + * as a fallback if no explicit `source`/`target` declaration carried + * a version segment). + */ +export function selectModelVersions( + structures: StructureDeclaration[] +): DetectedModelVersions { + let source: FhirVersion | undefined; + let queried: FhirVersion | undefined; + let target: FhirVersion | undefined; + let produced: FhirVersion | undefined; + + for (const s of structures) { + const v = s.fhirVersion ?? parseCanonicalVersion(s.url).version; + if (!v) continue; + switch (s.mode) { + case 'source': + if (!source) source = v; + break; + case 'queried': + if (!queried) queried = v; + break; + case 'target': + if (!target) target = v; + break; + case 'produced': + if (!produced) produced = v; + break; + } + } + + return { + sourceModelVersion: source ?? queried, + targetModelVersion: target ?? produced, + }; +} diff --git a/helpers/fml_models.ts b/helpers/fml_models.ts index 995330f5..e4fdf84b 100644 --- a/helpers/fml_models.ts +++ b/helpers/fml_models.ts @@ -27,6 +27,12 @@ export interface SourcePosition { endIndex: number; } +/** + * FHIR release identifier auto-detected from a (cross-)version canonical URL. + * See `helpers/fml_cross_version.ts`. + */ +export type FhirVersion = 'DSTU2' | 'STU3' | 'R4' | 'R4B' | 'R5' | 'R6'; + /** * Root structure representing a complete FML StructureMap */ @@ -54,6 +60,22 @@ export interface FmlStructureMap { /** Groups containing transformation rules */ groups: GroupDeclaration[]; + + /** + * FHIR release auto-detected from the first `uses ... as source` (or + * `as queried`) declaration whose canonical URL embeds a FHIR version + * segment. `undefined` when none of the source declarations carried a + * version segment; callers should fall back to a user override or + * global default. + */ + sourceModelVersion?: FhirVersion; + + /** + * FHIR release auto-detected from the first `uses ... as target` (or + * `as produced`) declaration whose canonical URL embeds a FHIR version + * segment. + */ + targetModelVersion?: FhirVersion; } /** @@ -150,7 +172,7 @@ export interface StructureDeclaration { /** Source position information */ position?: SourcePosition; - /** URL of the structure definition */ + /** URL of the structure definition (as written in the FML source) */ url: string; /** Optional alias for the structure */ @@ -158,6 +180,22 @@ export interface StructureDeclaration { /** How the structure is used: 'source', 'queried', 'target', or 'produced' */ mode: 'source' | 'queried' | 'target' | 'produced'; + + /** + * Version-neutral canonical URL to use when looking the structure up + * in a definition catalogue. For cross-version canonicals the + * embedded `.` segment is removed (e.g. + * `http://hl7.org/fhir/4.3/StructureDefinition/Citation` becomes + * `http://hl7.org/fhir/StructureDefinition/Citation`). For all other + * URLs this is identical to `url`. + */ + canonical?: string; + + /** + * FHIR release auto-detected from the URL's `.` version + * segment, or `undefined` when the URL was not version-qualified. + */ + fhirVersion?: FhirVersion; } /** diff --git a/helpers/fml_visitor.ts b/helpers/fml_visitor.ts index 23dc5c02..ae33c0ee 100644 --- a/helpers/fml_visitor.ts +++ b/helpers/fml_visitor.ts @@ -48,6 +48,7 @@ import type { GroupInvocation, InvocationParameter } from "./fml_models"; +import { parseCanonicalVersion, selectModelVersions } from "./fml_cross_version"; import type { ParserRuleContext } from "antlr4"; /** @@ -136,7 +137,8 @@ export class FmlModelBuilder { structures, imports, constants, - groups + groups, + ...selectModelVersions(structures) }; } @@ -253,13 +255,19 @@ export class FmlModelBuilder { visitMapDeclaration(ctx: MapDeclarationContext): MapDeclaration | null { const urlNode = ctx.url(); const idNode = ctx.identifier(); - - if (!urlNode || !idNode) return null; - + // The name can also be a double quoted string (a legacy format tolerated by the HAPI engine) + const quotedNameNode = ctx.DOUBLE_QUOTED_STRING(); + + if (!urlNode || (!idNode && !quotedNameNode)) return null; + + const identifier = idNode + ? this.visitIdentifier(idNode) + : this.removeQuotes(quotedNameNode.getText()); + return { position: this.getPosition(ctx), url: this.visitUrl(urlNode), - identifier: this.visitIdentifier(idNode) + identifier }; } @@ -280,12 +288,16 @@ export class FmlModelBuilder { if (text.includes('queried')) mode = 'queried'; else if (text.includes('target')) mode = 'target'; else if (text.includes('produced')) mode = 'produced'; - - return { + + const parsed = parseCanonicalVersion(url); + + return { position: this.getPosition(ctx), - url, - alias, - mode + url, + alias, + mode, + canonical: parsed.canonical, + fhirVersion: parsed.version }; } diff --git a/helpers/structuremap_diagram.ts b/helpers/structuremap_diagram.ts index 7a3aa0b9..4c044969 100644 --- a/helpers/structuremap_diagram.ts +++ b/helpers/structuremap_diagram.ts @@ -1,5 +1,6 @@ import { StructureMap, StructureMapGroupRule } from "fhir/r4b"; import type { TypeModel, ElementModel } from "./custom_model"; +import type { FhirVersion } from "./fml_models"; import { lookupByTypeName as lookupByTypeNameR4B } from "./models/generated/r4b"; /** @@ -8,6 +9,13 @@ import { lookupByTypeName as lookupByTypeNameR4B } from "./models/generated/r4b" */ export type TypeLookup = (typeName: string) => TypeModel | undefined; +/** + * Resolver that returns the {@link TypeLookup} for a given FHIR version. Used + * for cross-version maps where source and target structures belong to + * different FHIR releases. Return `undefined` to fall back to the default. + */ +export type LookupForVersion = (version: FhirVersion | undefined) => TypeLookup | undefined; + // ===== Exported Data Types ===== export interface StructureMapDiagram { @@ -29,6 +37,10 @@ export interface DiagramType { properties: PropertyEntry[]; /** Source position in the FML text for click-to-select on the type header */ fmlPosition?: { startIndex: number; endIndex: number }; + /** Detected FHIR version of the structure backing this box (cross-version + * maps). When set, the type model is resolved against the matching + * per-version dictionary rather than the default. */ + fhirVersion?: FhirVersion; } export interface PropertyEntry { @@ -218,7 +230,7 @@ function inferGroupInputTypes( * renderer can append `[]` for arrays and show the type in a tooltip. If * omitted, the bundled R4B dictionary is used as a sensible default. */ -export function extractStructureMapDiagram(map: StructureMap, typeLookup?: TypeLookup): StructureMapDiagram { +export function extractStructureMapDiagram(map: StructureMap, typeLookup?: TypeLookup, lookupForVersion?: LookupForVersion): StructureMapDiagram { const groups: DiagramGroup[] = []; nextRuleId = 0; const lookup = typeLookup ?? lookupByTypeNameR4B; @@ -255,6 +267,7 @@ export function extractStructureMapDiagram(map: StructureMap, typeLookup?: TypeL properties: entries, }; if ((input as any)._fmlPosition) dt.fmlPosition = (input as any)._fmlPosition; + if ((input as any)._fmlVersion) dt.fhirVersion = (input as any)._fmlVersion; if (input.mode === "source") sourceTypes.push(dt); else targetTypes.push(dt); } @@ -268,9 +281,12 @@ export function extractStructureMapDiagram(map: StructureMap, typeLookup?: TypeL // with isCollection (IsArray) and elementTypeName for tooltip display. for (const group of groups) { for (const dt of [...group.sourceTypes, ...group.targetTypes]) { + // For cross-version maps, resolve this box against the type model for + // its detected FHIR version; otherwise fall back to the default lookup. + const boxLookup = (lookupForVersion && lookupForVersion(dt.fhirVersion)) || lookup; // Either no declared type, or the declared type isn't in the model: // every property on this box is therefore unverifiable — flag them all. - const rootKnown = !!dt.typeName && !!lookup(dt.typeName); + const rootKnown = !!dt.typeName && !!boxLookup(dt.typeName); // Build a map of paths within this box that re-root to a created // type — so deeper properties like `entry.resource.status` resolve // against the created type (e.g. Observation) rather than the @@ -288,7 +304,7 @@ export function extractStructureMapDiagram(map: StructureMap, typeLookup?: TypeL continue; } if (!p.path || p.path === ".") continue; - const resolved = resolvePathInModel(dt.typeName, p.path, lookup, createBoundaries); + const resolved = resolvePathInModel(dt.typeName, p.path, boxLookup, createBoundaries); if (resolved) { if (resolved.isCollection) p.isCollection = true; if (resolved.elementTypeName) p.elementTypeName = resolved.elementTypeName; @@ -302,7 +318,7 @@ export function extractStructureMapDiagram(map: StructureMap, typeLookup?: TypeL if (p.createdType) { p.elementTypeName = p.createdType; if (resolved && resolved.element) { - if (!isCreatedTypeAllowed(resolved.element, p.createdType, lookup)) { + if (!isCreatedTypeAllowed(resolved.element, p.createdType, boxLookup)) { const allowed = describeAllowedTypes(resolved.element); const msg = `created type "${p.createdType}" is not allowed at ${dt.typeName}.${p.path} (allowed: ${allowed})`; console.warn(`[structuremap_diagram] ${msg}`); @@ -896,8 +912,8 @@ function countRuleDividers(propDisplay: PropertyDisplay[]): number { * Each group is rendered as a box containing source and target type boxes * with the properties read/written listed inside each type box. */ -export function generateStructureMapDiagramSvg(map: StructureMap, typeLookup?: TypeLookup): string { - const data = extractStructureMapDiagram(map, typeLookup); +export function generateStructureMapDiagramSvg(map: StructureMap, typeLookup?: TypeLookup, lookupForVersion?: LookupForVersion): string { + const data = extractStructureMapDiagram(map, typeLookup, lookupForVersion); if (data.groups.length === 0) { return [ diff --git a/helpers/structuremap_diagram_instance.ts b/helpers/structuremap_diagram_instance.ts index a3ec6098..2b5d799d 100644 --- a/helpers/structuremap_diagram_instance.ts +++ b/helpers/structuremap_diagram_instance.ts @@ -1,7 +1,8 @@ import { StructureMap, StructureMapGroupRule } from "fhir/r4b"; -import type { FmlStructureMap, Rule as FmlRule, RuleDependent } from "./fml_models"; +import type { FmlStructureMap, Rule as FmlRule, RuleDependent, FhirVersion } from "./fml_models"; import type { TypeModel, ElementModel } from "./custom_model"; import { lookupByTypeName as lookupByTypeNameR4B } from "./models/generated/r4b"; +import { parseCanonicalVersion } from "./fml_cross_version"; /** * Function used to resolve a TypeModel by its TypeName. Pass any per-version @@ -9,6 +10,14 @@ import { lookupByTypeName as lookupByTypeNameR4B } from "./models/generated/r4b" */ export type TypeLookup = (typeName: string) => TypeModel | undefined; +/** + * Resolver that returns the {@link TypeLookup} for a given FHIR version. Used + * for cross-version maps where source and target structures belong to + * different FHIR releases (e.g. an R4B → R5 transform). Return `undefined` to + * fall back to the default lookup. + */ +export type LookupForVersion = (version: FhirVersion | undefined) => TypeLookup | undefined; + // ===== Exported Data Types ===== export interface StructureMapDiagram { @@ -32,6 +41,10 @@ export interface DiagramType { properties: PropertyEntry[]; /** Source position in the FML text for click-to-select on the type header */ fmlPosition?: { startIndex: number; endIndex: number }; + /** Detected FHIR version of the structure backing this box (cross-version + * maps). When set, the type model for this box is resolved against the + * matching per-version dictionary rather than the default. */ + fhirVersion?: FhirVersion; /** When true, this DiagramType represents a "computed value" source * produced by a variable-only target rule (e.g. `uuid() as fullUrl`, * `cc('http://loinc.org', '8302-2', 'Body height') as coding`). It @@ -127,7 +140,7 @@ interface VarInfo { * renderer can append `[]` for arrays and show the type in a tooltip. If * omitted, the bundled R4B dictionary is used as a sensible default. */ -export function extractStructureMapDiagram(map: StructureMap, typeLookup?: TypeLookup, showMissingProperties?: boolean): StructureMapDiagram { +export function extractStructureMapDiagram(map: StructureMap, typeLookup?: TypeLookup, showMissingProperties?: boolean, lookupForVersion?: LookupForVersion): StructureMapDiagram { const groups: DiagramGroup[] = []; nextRuleId = 0; nextConnectionId = 0; @@ -174,6 +187,7 @@ export function extractStructureMapDiagram(map: StructureMap, typeLookup?: TypeL properties: entries, }; if ((input as any)._fmlPosition) dt.fmlPosition = (input as any)._fmlPosition; + if ((input as any)._fmlVersion) dt.fhirVersion = (input as any)._fmlVersion; if (input.mode === "source") sourceTypes.push(dt); else targetTypes.push(dt); } @@ -286,9 +300,12 @@ export function extractStructureMapDiagram(map: StructureMap, typeLookup?: TypeL // path is the literal rule text — there's no element to resolve // against the type model, so skip the annotation pass entirely. if (dt.isComputed) continue; + // For cross-version maps, resolve this box against the type model for + // its detected FHIR version; otherwise fall back to the default lookup. + const boxLookup = (lookupForVersion && lookupForVersion(dt.fhirVersion)) || lookup; // Either no declared type, or the declared type isn't in the model: // every property on this box is therefore unverifiable — flag them all. - const rootKnown = !!dt.typeName && !!lookup(dt.typeName); + const rootKnown = !!dt.typeName && !!boxLookup(dt.typeName); // Build a map of paths within this box that re-root to a created // type — so deeper properties like `entry.resource.status` resolve // against the created type (e.g. Observation) rather than the @@ -306,7 +323,7 @@ export function extractStructureMapDiagram(map: StructureMap, typeLookup?: TypeL } // Skip the root-context placeholder ("." path) which has no element. if (!p.path || p.path === ".") continue; - const resolved = resolvePathInModel(dt.typeName, p.path, lookup, createBoundaries); + const resolved = resolvePathInModel(dt.typeName, p.path, boxLookup, createBoundaries); if (resolved) { if (resolved.isCollection) p.isCollection = true; if (resolved.elementTypeName) p.elementTypeName = resolved.elementTypeName; @@ -320,7 +337,7 @@ export function extractStructureMapDiagram(map: StructureMap, typeLookup?: TypeL if (p.createdType) { p.elementTypeName = p.createdType; if (resolved && resolved.element) { - if (!isCreatedTypeAllowed(resolved.element, p.createdType, lookup)) { + if (!isCreatedTypeAllowed(resolved.element, p.createdType, boxLookup)) { const allowed = describeAllowedTypes(resolved.element); const displayPath = stripPathDiscriminators(p.path); const msg = `created type "${p.createdType}" is not allowed at ${dt.typeName}.${displayPath} (allowed: ${allowed})`; @@ -1508,8 +1525,8 @@ function renderSankeyRibbon( * Each group is rendered as a box containing source and target type boxes * with the properties read/written listed inside each type box. */ -export function generateInstanceDiagramSvg(map: StructureMap, typeLookup?: TypeLookup, showMissingProperties?: boolean): string { - const data = extractStructureMapDiagram(map, typeLookup, showMissingProperties); +export function generateInstanceDiagramSvg(map: StructureMap, typeLookup?: TypeLookup, showMissingProperties?: boolean, lookupForVersion?: LookupForVersion): string { + const data = extractStructureMapDiagram(map, typeLookup, showMissingProperties, lookupForVersion); if (data.groups.length === 0) { return [ @@ -2266,8 +2283,45 @@ function convertFmlRules(rules: FmlRule[]): StructureMapGroupRule[] { * Convert an FmlStructureMap (from the local FML parser) into a minimal FHIR * StructureMap resource — just enough for `extractStructureMapDiagram` / * `generateInstanceDiagramSvg` to work. + * + * Group input types in FML often reference a `uses ... alias X` declaration + * rather than a bare FHIR type name. For (cross-version) maps the alias hides + * both the real type (e.g. `Appointment`) and the FHIR version segment in the + * canonical (e.g. `http://hl7.org/fhir/4.3/StructureDefinition/Appointment`). + * This resolves each input's declared type back through the `uses` structures + * so the diagram can (a) look the type up in the model by its real name and + * (b) pick the right per-version model. The resolved version is stashed on + * `input._fmlVersion` for the diagram extractor. */ export function fmlToStructureMapForDiagram(fml: FmlStructureMap): StructureMap { + // Index the `uses` declarations by their alias and by their resolved type + // name so a group input's declared type can be traced back to the structure + // (and hence canonical + FHIR version) that introduced it. + interface ResolvedStructure { typeName: string; version?: FhirVersion; mode: string; } + const byAlias = new Map(); + const byTypeName = new Map(); + for (const s of fml.structures || []) { + const parsed = parseCanonicalVersion(s.url); + const canonical = s.canonical ?? parsed.canonical; + const version = s.fhirVersion ?? parsed.version; + // The version-neutral canonical ends in `.../StructureDefinition/`. + const typeName = canonical.split("/").pop() || canonical; + const resolved: ResolvedStructure = { typeName, version, mode: s.mode }; + if (s.alias) byAlias.set(s.alias, resolved); + if (!byTypeName.has(typeName)) byTypeName.set(typeName, resolved); + } + + const resolveInput = (declaredType: string | undefined, mode: "source" | "target") => { + if (!declaredType) return { type: declaredType, version: undefined as FhirVersion | undefined }; + const match = byAlias.get(declaredType) ?? byTypeName.get(declaredType); + const type = match?.typeName ?? declaredType; + // Per-structure version wins; otherwise fall back to the map-level + // auto-detected source/target model version. + const version = match?.version + ?? (mode === "source" ? fml.sourceModelVersion : fml.targetModelVersion); + return { type, version }; + }; + return { resourceType: "StructureMap", status: "draft", @@ -2278,11 +2332,13 @@ export function fmlToStructureMapForDiagram(fml: FmlStructureMap): StructureMap name: g.name, typeMode: "none" as any, input: g.parameters.map((p) => { + const { type, version } = resolveInput(p.type, p.mode); const inp: any = { name: p.name, - type: p.type, + type, mode: p.mode as any, }; + if (version) inp._fmlVersion = version; if (p.position) inp._fmlPosition = { startIndex: p.position.startIndex, endIndex: p.position.endIndex }; return inp; }), diff --git a/pages/fml.vue b/pages/fml.vue index 7bb9310b..acf8435d 100644 --- a/pages/fml.vue +++ b/pages/fml.vue @@ -425,11 +425,14 @@ import Chat from "~/components/Chat.vue"; import ResourceEditor from "~/components/ResourceEditor.vue"; import { parseFML } from "~/helpers/fml_parser"; -import type { FmlStructureMap } from "~/helpers/fml_models"; +import type { FmlStructureMap, FhirVersion } from "~/helpers/fml_models"; import { generateInstanceDiagramSvg, fmlToStructureMapForDiagram } from "~/helpers/structuremap_diagram_instance"; import { highlightDiagramConnection, findConnectionIdsForClick } from "~/helpers/diagram_interaction"; import { generateStructureMapDiagramSvg } from "~/helpers/structuremap_diagram"; import { lookupByTypeName as lookupByTypeNameR4B } from "~/helpers/models/generated/r4b"; +import { lookupByTypeName as lookupByTypeNameR4 } from "~/helpers/models/generated/r4"; +import { lookupByTypeName as lookupByTypeNameR5 } from "~/helpers/models/generated/r5"; +import { lookupByTypeName as lookupByTypeNameR6 } from "~/helpers/models/generated/r6"; import { buildUserModelLookup, composeLookups, type TypeLookup, type UserModelLookup } from "~/helpers/user_models"; import xmlFormat from 'xml-formatter'; import { createFhirLogicalModel, CreateLogicalModelOptions } from '~/helpers/logical_model_generator'; @@ -780,7 +783,7 @@ export default Vue.extend({ iconName: "mdi-file-document-outline", tabName: "Instance", title: "Instance-level view showing source/target objects with mapped and unmapped properties", - show: this.showAdvancedSettings, + show: true, enabled: true, }, { @@ -832,6 +835,22 @@ export default Vue.extend({ return composeLookups(this.userModelLookup?.lookup, lookupByTypeNameR4B); }, + /** Resolve the type-model lookup for a specific FHIR version, used by the + * diagrams for cross-version maps (e.g. an R4B → R5 transform). The + * per-version dictionary is composed with any user-supplied models so + * user overrides still win. Versions without a bundled dictionary + * (DSTU2/STU3) and the `undefined` case fall back to the default. */ + lookupForVersion(version?: FhirVersion): TypeLookup | undefined { + const base = + version === "R4" ? lookupByTypeNameR4 + : version === "R4B" ? lookupByTypeNameR4B + : version === "R5" ? lookupByTypeNameR5 + : version === "R6" ? lookupByTypeNameR6 + : undefined; + if (!base) return undefined; + return composeLookups(this.userModelLookup?.lookup, base); + }, + /** Debounced trigger for instance/structure-map diagram regeneration. * Mirrors the keystroke-debounce used elsewhere on the page. */ scheduleDiagramRegen() { @@ -1615,8 +1634,9 @@ group SetEntryData(source src: Patient, target entry) try { const fhirMap = fmlToStructureMapForDiagram(fmlMap); const lookup = this.composedTypeLookup(); - this.instanceSvg = generateInstanceDiagramSvg(fhirMap, lookup, true); - this.diagramSvg = generateStructureMapDiagramSvg(fhirMap, lookup); + const lookupForVersion = (v?: FhirVersion) => this.lookupForVersion(v); + this.instanceSvg = generateInstanceDiagramSvg(fhirMap, lookup, true, lookupForVersion); + this.diagramSvg = generateStructureMapDiagramSvg(fhirMap, lookup, lookupForVersion); } catch (e) { console.error('Failed to generate instance diagram:', e); this.instanceSvg = undefined; @@ -1922,8 +1942,9 @@ group SetEntryData(source src: Patient, target entry) try { const fhirMap = fmlToStructureMapForDiagram(fmlMap); const lookup = this.composedTypeLookup(); - this.instanceSvg = generateInstanceDiagramSvg(fhirMap, lookup, true); - this.diagramSvg = generateStructureMapDiagramSvg(fhirMap, lookup); + const lookupForVersion = (v?: FhirVersion) => this.lookupForVersion(v); + this.instanceSvg = generateInstanceDiagramSvg(fhirMap, lookup, true, lookupForVersion); + this.diagramSvg = generateStructureMapDiagramSvg(fhirMap, lookup, lookupForVersion); } catch (e) { console.error('Failed to generate instance diagram:', e); this.instanceSvg = undefined; diff --git a/test/fml-cross-version-diagram.test.ts b/test/fml-cross-version-diagram.test.ts new file mode 100644 index 00000000..68cbe07c --- /dev/null +++ b/test/fml-cross-version-diagram.test.ts @@ -0,0 +1,93 @@ +// Tests that the FML diagram pipeline is cross-version aware: aliases on +// version-qualified `uses` declarations are resolved back to their underlying +// FHIR type and resolved against the model for the right FHIR release. +import { describe, expect, test } from "@jest/globals"; +import { parseFML } from "../helpers/fml_parser"; +import { + fmlToStructureMapForDiagram, + extractStructureMapDiagram, +} from "../helpers/structuremap_diagram_instance"; +import { lookupByTypeName as lookupR4B } from "../helpers/models/generated/r4b"; +import { lookupByTypeName as lookupR5 } from "../helpers/models/generated/r5"; +import type { FmlStructureMap, FhirVersion } from "../helpers/fml_models"; + +// Cross-version Appointment map (R4B -> R5) using version-qualified canonicals +// with aliases, mirroring the HL7 fhir-cross-version maps. +const APPOINTMENT_FML = `/// url = "http://hl7.org/fhir/uv/xver/StructureMap/Appointment4Bto5" +/// name = "Appointment4Bto5" + +uses "http://hl7.org/fhir/4.3/StructureDefinition/Appointment" alias AppointmentR4B as source +uses "http://hl7.org/fhir/5.0/StructureDefinition/Appointment" alias AppointmentR5 as target + +group Appointment(source src : AppointmentR4B, target tgt : AppointmentR5) { + src.identifier -> tgt.identifier; + src.specialty -> tgt.specialty; + src.appointmentType -> tgt.appointmentType; + src.reasonCode -> tgt.reason; +} +`; + +/** Version-aware resolver matching what pages/fml.vue wires up. */ +const lookupForVersion = (v?: FhirVersion) => + v === "R5" ? lookupR5 : v === "R4B" ? lookupR4B : undefined; + +describe("fmlToStructureMapForDiagram cross-version alias resolution", () => { + test("resolves aliases to the underlying FHIR type and tags the version", () => { + const fml = parseFML(APPOINTMENT_FML) as FmlStructureMap; + expect((fml as any).resourceType).toBeUndefined(); + + const map = fmlToStructureMapForDiagram(fml); + const inputs = map.group[0].input!; + + const src = inputs.find((i) => i.name === "src") as any; + const tgt = inputs.find((i) => i.name === "tgt") as any; + + // The alias (AppointmentR4B / AppointmentR5) must be resolved to the real + // type name so the diagram can look it up in the model dictionary. + expect(src.type).toBe("Appointment"); + expect(tgt.type).toBe("Appointment"); + // ...and tagged with the detected FHIR version for per-version lookup. + expect(src._fmlVersion).toBe("R4B"); + expect(tgt._fmlVersion).toBe("R5"); + }); +}); + +describe("extractStructureMapDiagram cross-version resolution", () => { + test("source resolves against R4B and target against R5", () => { + const fml = parseFML(APPOINTMENT_FML) as FmlStructureMap; + const map = fmlToStructureMapForDiagram(fml); + + const diagram = extractStructureMapDiagram(map, lookupR4B, true, lookupForVersion); + const group = diagram.groups[0]; + + const srcBox = group.sourceTypes[0]; + const tgtBox = group.targetTypes[0]; + + expect(srcBox.typeName).toBe("Appointment"); + expect(srcBox.fhirVersion).toBe("R4B"); + expect(tgtBox.typeName).toBe("Appointment"); + expect(tgtBox.fhirVersion).toBe("R5"); + + const unknownPaths = (box: typeof srcBox) => + box.properties.filter((p) => p.unknownElement).map((p) => p.path); + + // Every property must resolve against its version's model. Notably + // `reasonCode` exists only in R4B and `reason` only in R5 — they would be + // flagged as unknown if both boxes used the same (wrong) model. + expect(unknownPaths(srcBox)).toEqual([]); + expect(unknownPaths(tgtBox)).toEqual([]); + }); + + test("R5-only target element is flagged when the version resolver is absent", () => { + // Without the version-aware resolver, both boxes fall back to R4B; the + // R5-only `tgt.reason` element should then be reported as unknown. This + // guards against a regression where version awareness is silently lost. + const fml = parseFML(APPOINTMENT_FML) as FmlStructureMap; + const map = fmlToStructureMapForDiagram(fml); + + const diagram = extractStructureMapDiagram(map, lookupR4B, true); + const tgtBox = diagram.groups[0].targetTypes[0]; + const reason = tgtBox.properties.find((p) => p.path === "reason"); + expect(reason?.unknownElement).toBe(true); + }); +}); diff --git a/test/fml-cross-version.test.ts b/test/fml-cross-version.test.ts new file mode 100644 index 00000000..98a89af2 --- /dev/null +++ b/test/fml-cross-version.test.ts @@ -0,0 +1,222 @@ +import { describe, expect, test } from "@jest/globals"; +import { + parseCanonicalVersion, + selectModelVersions, +} from "../helpers/fml_cross_version"; +import { parseFML } from "../helpers/fml_parser"; +import type { FmlStructureMap } from "../helpers/fml_models"; + +describe("parseCanonicalVersion", () => { + test("strips R4B version segment from a cross-version canonical", () => { + const r = parseCanonicalVersion( + "http://hl7.org/fhir/4.3/StructureDefinition/Citation" + ); + expect(r.version).toBe("R4B"); + expect(r.canonical).toBe( + "http://hl7.org/fhir/StructureDefinition/Citation" + ); + }); + + test("strips R5 version segment from a cross-version canonical", () => { + const r = parseCanonicalVersion( + "http://hl7.org/fhir/5.0/StructureDefinition/Citation" + ); + expect(r.version).toBe("R5"); + expect(r.canonical).toBe( + "http://hl7.org/fhir/StructureDefinition/Citation" + ); + }); + + test.each([ + ["1.0", "DSTU2"], + ["3.0", "STU3"], + ["4.0", "R4"], + ["4.3", "R4B"], + ["5.0", "R5"], + ["6.0", "R6"], + ])("recognises %s as %s", (segment, version) => { + const r = parseCanonicalVersion( + `http://hl7.org/fhir/${segment}/StructureDefinition/Patient` + ); + expect(r.version).toBe(version); + expect(r.canonical).toBe( + "http://hl7.org/fhir/StructureDefinition/Patient" + ); + }); + + test("leaves a plain version-neutral canonical untouched", () => { + const url = "http://hl7.org/fhir/StructureDefinition/Patient"; + const r = parseCanonicalVersion(url); + expect(r.version).toBeUndefined(); + expect(r.canonical).toBe(url); + }); + + test("leaves an unrelated logical model URL untouched", () => { + const url = "http://example.org/fhir/StructureDefinition/MyLogical"; + const r = parseCanonicalVersion(url); + expect(r.version).toBeUndefined(); + expect(r.canonical).toBe(url); + }); + + test("leaves an hl7.org URL with an unrecognised version segment untouched", () => { + const url = "http://hl7.org/fhir/9.9/StructureDefinition/Foo"; + const r = parseCanonicalVersion(url); + expect(r.version).toBeUndefined(); + expect(r.canonical).toBe(url); + }); + + test("handles empty input", () => { + const r = parseCanonicalVersion(""); + expect(r.version).toBeUndefined(); + expect(r.canonical).toBe(""); + }); +}); + +describe("selectModelVersions", () => { + test("picks first source/target with version segments", () => { + const detected = selectModelVersions([ + { + url: "http://hl7.org/fhir/4.3/StructureDefinition/Citation", + mode: "source", + canonical: "http://hl7.org/fhir/StructureDefinition/Citation", + fhirVersion: "R4B", + }, + { + url: "http://hl7.org/fhir/5.0/StructureDefinition/Citation", + mode: "target", + canonical: "http://hl7.org/fhir/StructureDefinition/Citation", + fhirVersion: "R5", + }, + ]); + expect(detected.sourceModelVersion).toBe("R4B"); + expect(detected.targetModelVersion).toBe("R5"); + }); + + test("falls back to queried/produced if no source/target carry versions", () => { + const detected = selectModelVersions([ + { + url: "http://hl7.org/fhir/4.3/StructureDefinition/Citation", + mode: "queried", + canonical: "http://hl7.org/fhir/StructureDefinition/Citation", + fhirVersion: "R4B", + }, + { + url: "http://hl7.org/fhir/5.0/StructureDefinition/Citation", + mode: "produced", + canonical: "http://hl7.org/fhir/StructureDefinition/Citation", + fhirVersion: "R5", + }, + ]); + expect(detected.sourceModelVersion).toBe("R4B"); + expect(detected.targetModelVersion).toBe("R5"); + }); + + test("explicit source wins over queried even if listed later", () => { + const detected = selectModelVersions([ + { + url: "http://hl7.org/fhir/5.0/StructureDefinition/Foo", + mode: "queried", + fhirVersion: "R5", + }, + { + url: "http://hl7.org/fhir/4.3/StructureDefinition/Bar", + mode: "source", + fhirVersion: "R4B", + }, + ]); + expect(detected.sourceModelVersion).toBe("R4B"); + }); + + test("returns undefined when no canonical carries a version segment", () => { + const detected = selectModelVersions([ + { + url: "http://hl7.org/fhir/StructureDefinition/Patient", + mode: "source", + }, + { + url: "http://hl7.org/fhir/StructureDefinition/Bundle", + mode: "target", + }, + ]); + expect(detected.sourceModelVersion).toBeUndefined(); + expect(detected.targetModelVersion).toBeUndefined(); + }); +}); + +describe("parseFML cross-version detection", () => { + test("Citation R4B -> R5 map detects source=R4B target=R5 and normalises canonicals", () => { + const fml = `map "http://hl7.org/fhir/uv/xver/StructureMap/Citation4Bto5" = Citation4Bto5 + +uses "http://hl7.org/fhir/4.3/StructureDefinition/Citation" alias CitationR4B as source +uses "http://hl7.org/fhir/5.0/StructureDefinition/Citation" alias CitationR5 as target + +group Citation(source src : CitationR4B, target tgt : CitationR5) { + src.id -> tgt.id; +} +`; + const result = parseFML(fml); + // Should be a successful parse, not an OperationOutcome + expect((result as any).resourceType).toBeUndefined(); + const map = result as FmlStructureMap; + + expect(map.sourceModelVersion).toBe("R4B"); + expect(map.targetModelVersion).toBe("R5"); + + const src = map.structures.find((s) => s.mode === "source"); + const tgt = map.structures.find((s) => s.mode === "target"); + expect(src).toBeDefined(); + expect(tgt).toBeDefined(); + expect(src!.fhirVersion).toBe("R4B"); + expect(tgt!.fhirVersion).toBe("R5"); + expect(src!.canonical).toBe( + "http://hl7.org/fhir/StructureDefinition/Citation" + ); + expect(tgt!.canonical).toBe( + "http://hl7.org/fhir/StructureDefinition/Citation" + ); + }); + + test("plain canonicals leave model versions undefined and canonical unchanged", () => { + const fml = `map "http://example.org/StructureMap/x" = X + +uses "http://hl7.org/fhir/StructureDefinition/Patient" as source +uses "http://hl7.org/fhir/StructureDefinition/Bundle" as target + +group g(source src : Patient, target tgt : Bundle) { + src.id -> tgt.id; +} +`; + const result = parseFML(fml); + expect((result as any).resourceType).toBeUndefined(); + const map = result as FmlStructureMap; + + expect(map.sourceModelVersion).toBeUndefined(); + expect(map.targetModelVersion).toBeUndefined(); + + const src = map.structures.find((s) => s.mode === "source"); + expect(src!.fhirVersion).toBeUndefined(); + expect(src!.canonical).toBe( + "http://hl7.org/fhir/StructureDefinition/Patient" + ); + }); + + test("accepts a legacy double quoted map name (tolerated by the HAPI engine)", () => { + const fml = `map "http://github.com/FHIR/fhir-test-cases/r5/fml/syntax" = "Syntax" + +uses "http://hl7.org/fhir/StructureDefinition/Patient" alias Patient as source +uses "http://hl7.org/fhir/StructureDefinition/Basic" alias Basic as target + +group Patient(source src : Patient, target tgt : Basic) { + src.identifier -> tgt.identifier; +} +`; + const result = parseFML(fml); + // Should be a successful parse, not an OperationOutcome + expect((result as any).resourceType).toBeUndefined(); + const map = result as FmlStructureMap; + + // The surrounding double quotes should be stripped from the name + expect(map.mapDeclaration?.identifier).toBe("Syntax"); + expect(map.groups.map((g) => g.name)).toEqual(["Patient"]); + }); +});