exiftool-vendored.pl 12.89.0 → 12.96.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,7 +16,7 @@ use strict;
16
16
  use vars qw($VERSION);
17
17
  use Image::ExifTool qw(:DataAccess :Utils);
18
18
 
19
- $VERSION = '1.39';
19
+ $VERSION = '1.40';
20
20
 
21
21
  sub ProcessJpeg2000Box($$$);
22
22
  sub ProcessJUMD($$$);
@@ -1442,7 +1442,7 @@ sub ProcessBrotli($$$)
1442
1442
  }
1443
1443
  } elsif ($type eq 'jumb') {
1444
1444
  return undef if $isWriting; # (can't yet write JUMBF)
1445
- Image::ExifTool::ProcessJUMB($et, \%dirInfo, $tagTablePtr); # (untested)
1445
+ Image::ExifTool::Jpeg2000::ProcessJUMB($et, \%dirInfo, $tagTablePtr); # (untested)
1446
1446
  }
1447
1447
  if ($isWriting) {
1448
1448
  return undef unless defined $dat;
@@ -65,7 +65,7 @@ use Image::ExifTool::Exif;
65
65
  use Image::ExifTool::GPS;
66
66
  use Image::ExifTool::XMP;
67
67
 
68
- $VERSION = '4.35';
68
+ $VERSION = '4.37';
69
69
 
70
70
  sub LensIDConv($$$);
71
71
  sub ProcessNikonAVI($$$);
@@ -367,6 +367,7 @@ sub GetAFPointGrid($$;$);
367
367
  '02 46 37 37 25 25 02 00' => 'Sigma 24mm F2.8 Super Wide II Macro',
368
368
  '7E 54 37 37 0C 0C 4B 06' => 'Sigma 24mm F1.4 DG HSM | A', #30
369
369
  '26 58 3C 3C 14 14 1C 02' => 'Sigma 28mm F1.8 EX DG Aspherical Macro',
370
+ 'BC 54 3C 3C 0C 0C 4B 46' => 'Sigma 28mm F1.4 DG HSM | A', #30
370
371
  '48 54 3E 3E 0C 0C 4B 06' => 'Sigma 30mm F1.4 EX DC HSM',
371
372
  'F8 54 3E 3E 0C 0C 4B 06' => 'Sigma 30mm F1.4 EX DC HSM', #JD
372
373
  '91 54 44 44 0C 0C 4B 06' => 'Sigma 35mm F1.4 DG HSM', #30
@@ -2495,6 +2496,7 @@ my %base64coord = (
2495
2496
  { # D7100=0227
2496
2497
  Condition => '$$valPt =~ /^0[28]/',
2497
2498
  Name => 'ShotInfo02xx',
2499
+ Drop => 50000, # drop if too large (>64k for Z6iii)
2498
2500
  SubDirectory => {
2499
2501
  TagTable => 'Image::ExifTool::Nikon::ShotInfo',
2500
2502
  ProcessProc => \&ProcessNikonEncrypted,
@@ -5635,6 +5637,38 @@ my %nikonFocalConversions = (
5635
5637
  Notes => 'P6000',
5636
5638
  PrintConv => \%offOn,
5637
5639
  },
5640
+ # for Nikon Z6iii JPG and RAW images (version 0809),
5641
+ # the offset table starts at 0x24 and is as follows
5642
+ # JPG Offset Size NEF Offset Size
5643
+ # 0) 0x0000 0 0) 0x009c 21604
5644
+ # 1) 0x0000 0 1) 0x5500 6008
5645
+ # 2) 0x009c 2528 2) 0x6c78 2528
5646
+ # 3) 0x0a7c 200 3) 0x7658 200
5647
+ # 4) 0x0b44 2488 4) 0x7720 2488
5648
+ # 5) 0x14fc 1468 5) 0x80d8 1468
5649
+ # 6) 0x1ab8 1032 6) 0x8694 1032
5650
+ # 7) 0x1ec0 256 7) 0x8a9c 256
5651
+ # 8) 0x1fc0 800 8) 0x8b9c 800
5652
+ # 9) 0x22e0 144 9) 0x8ebc 144
5653
+ # 10) 0x2370 64 10) 0x8f4c 64
5654
+ # 11) 0x0000 0 11) 0x0000 0
5655
+ # 12) 0x23b0 5009 12) 0x8f8c 5009
5656
+ # 13) 0x3741 1536 13) 0xa31d 1536
5657
+ # 14) 0x3d41 11928 14) 0xa91d 11928
5658
+ # 15) 0x6bd9 5937 15) 0xd7b5 5937
5659
+ # 16) 0x830a 500 16) 0xeee6 500
5660
+ # 17) 0x84fe 160 17) 0xf0da 160
5661
+ # 18) 0x859e 464 18) 0xf17a 464
5662
+ # 19) 0x876e 8 19) 0xf34a 8
5663
+ # 20) 0x8776 64 20) 0xf352 64
5664
+ # 21) 0x87b6 6 21) 0xf392 6
5665
+ # 22) 0x87bc 48 22) 0xf398 48
5666
+ # 23) 0x87ec 20 23) 0xf3c8 20
5667
+ # 24) 0x8800 108 24) 0xf3dc 108
5668
+ # 25) 0x886c 8 25) 0xf448 8
5669
+ # 26) 0x8874 2420 26) 0xf450 2420
5670
+ # 27) 0x0000 0 27) 0x0000 0
5671
+ # 28) 0x0000 0 28) 0x0000 0
5638
5672
  0x66 => {
5639
5673
  Name => 'VR_0x66',
5640
5674
  Condition => '$$self{ShotInfoVersion} eq "0204"',
@@ -17,12 +17,57 @@ use strict;
17
17
  use vars qw($VERSION);
18
18
  use Image::ExifTool qw(:DataAccess :Utils);
19
19
 
20
- $VERSION = '1.07';
20
+ $VERSION = '1.08';
21
21
 
22
22
  sub ProcessNikonSettings($$$);
23
23
 
24
24
  my %enableDisable = ( 1 => 'Enable', 2 => 'Disable' );
25
25
 
26
+ my %funcButtonZ6 = ( #forum16316
27
+ 1 => 'AF-On or Subject Tracking', # (bug in 3.xx firmware?)
28
+ 2 => 'AF Lock Only',
29
+ 3 => 'AE Lock (hold)',
30
+ 4 => 'AE Lock (reset on release)',
31
+ 5 => 'AE Lock Only',
32
+ 6 => 'AE/AF Lock',
33
+ 7 => 'FV Lock',
34
+ 8 => 'Flash Disable/Enable',
35
+ 9 => 'Preview',
36
+ 10 => 'Matrix Metering',
37
+ 11 => 'Center-weighted Metering',
38
+ 12 => 'Spot Metering',
39
+ 13 => 'Highlight-weighted Metering',
40
+ 14 => 'Bracketing Burst',
41
+ 15 => 'Synchronized Release (Master)',
42
+ 16 => 'Synchronized Release (Remote)', # no settings map to 17 or 18
43
+ 19 => '+NEF(RAW)',
44
+ 20 => 'Framing Grid Display',
45
+ # 21 - missing
46
+ 22 => 'Zoom On/Off',
47
+ # 23 - missing
48
+ 24 => 'My Menu',
49
+ 25 => 'My Menu Top Item',
50
+ 26 => 'Playback',
51
+ 27 => 'Protect',
52
+ 28 => 'Image Area',
53
+ 29 => 'Image Quality',
54
+ 30 => 'White Balance',
55
+ 31 => 'Picture Control',
56
+ 32 => 'Active D-Lighting',
57
+ 33 => 'Metering',
58
+ 34 => 'Flash Mode',
59
+ 35 => 'Focus Mode',
60
+ 36 => 'Auto Bracketing',
61
+ 37 => 'Multiple Exposure',
62
+ 38 => 'HDR',
63
+ 39 => 'Exposure Delay Mode',
64
+ 40 => 'Shutter/Aperture Lock',
65
+ 41 => 'Focus Peaking',
66
+ 42 => 'Rating',
67
+ 43 => 'Non-CPU Lens',
68
+ 44 => 'None',
69
+ );
70
+
26
71
  my %funcButtonZ7m2 = (
27
72
  1 => 'AF-On',
28
73
  2 => 'AF Lock Only',
@@ -1117,6 +1162,11 @@ my %infoZSeries = (
1117
1162
  Name => 'Func1Button',
1118
1163
  PrintConv => \%previewButtonD6,
1119
1164
  %infoD6,
1165
+ },{ # CSf2-a (Z6)
1166
+ Name => 'Func1Button',
1167
+ Condition => '$$self{Model} =~ /^NIKON Z [67]\b/',
1168
+ Notes => 'Z6 and Z7',
1169
+ PrintConv => \%funcButtonZ6,
1120
1170
  },{ # CSf2-a (Z7_2)
1121
1171
  Name => 'Func1Button',
1122
1172
  PrintConv => \%funcButtonZ7m2,
@@ -1126,6 +1176,11 @@ my %infoZSeries = (
1126
1176
  Name => 'Func2Button',
1127
1177
  PrintConv => \%previewButtonD6,
1128
1178
  %infoD6,
1179
+ },{ # CSf2-b (Z6)
1180
+ Name => 'Func2Button',
1181
+ Condition => '$$self{Model} =~ /^NIKON Z [67]\b/',
1182
+ Notes => 'Z6 and Z7',
1183
+ PrintConv => \%funcButtonZ6,
1129
1184
  },{ # CSf2-b (Z7_2)
1130
1185
  Name => 'Func2Button',
1131
1186
  PrintConv => \%funcButtonZ7m2,
@@ -16,7 +16,7 @@ use vars qw($VERSION);
16
16
  use Image::ExifTool qw(:DataAccess :Utils);
17
17
  use Image::ExifTool::GPS;
18
18
 
19
- $VERSION = '1.06';
19
+ $VERSION = '1.07';
20
20
 
21
21
  # supported EXR value format types (other types are extracted as undef binary data)
22
22
  my %formatType = (
@@ -91,6 +91,8 @@ my %formatType = (
91
91
  5 => 'PXR24',
92
92
  6 => 'B44',
93
93
  7 => 'B44A',
94
+ 8 => 'DWAA', #github276
95
+ 9 => 'DWAB', #github276
94
96
  },
95
97
  },
96
98
  dataWindow => { },
@@ -36,7 +36,7 @@ use strict;
36
36
  use vars qw($VERSION $AUTOLOAD %stdCase);
37
37
  use Image::ExifTool qw(:DataAccess :Utils);
38
38
 
39
- $VERSION = '1.67';
39
+ $VERSION = '1.68';
40
40
 
41
41
  sub ProcessPNG_tEXt($$$);
42
42
  sub ProcessPNG_iTXt($$$);
@@ -1400,7 +1400,7 @@ sub ProcessPNG($$)
1400
1400
  my $fastScan = $et->Options('FastScan');
1401
1401
  my $hash = $$et{ImageDataHash};
1402
1402
  my ($n, $sig, $err, $hbuf, $dbuf, $cbuf);
1403
- my ($wasHdr, $wasEnd, $wasDat, $doTxt, @txtOffset);
1403
+ my ($wasHdr, $wasEnd, $wasDat, $doTxt, @txtOffset, $wasTrailer);
1404
1404
 
1405
1405
  # check to be sure this is a valid PNG/MNG/JNG image
1406
1406
  return 0 unless $raf->Read($sig,8) == 8 and $pngLookup{$sig};
@@ -1461,6 +1461,7 @@ sub ProcessPNG($$)
1461
1461
  if ($wasEnd) {
1462
1462
  last unless $n; # stop now if normal end of PNG
1463
1463
  $et->WarnOnce("Trailer data after $fileType $endChunk chunk", 1);
1464
+ $wasTrailer = 1;
1464
1465
  last if $n < 8;
1465
1466
  $$et{SET_GROUP1} = 'Trailer';
1466
1467
  } elsif ($n != 8) {
@@ -1654,6 +1655,13 @@ sub ProcessPNG($$)
1654
1655
  }
1655
1656
  }
1656
1657
  delete $$et{SET_GROUP1};
1658
+ # read Samsung trailer if it exists
1659
+ if ($wasTrailer and not $outfile and $raf->Seek(-8, 2) and
1660
+ $raf->Read($dbuf,8) and $dbuf =~ /\0\0(QDIOBS|SEFT)$/) # (have only seen SEFT type)
1661
+ {
1662
+ require Image::ExifTool::Samsung;
1663
+ Image::ExifTool::Samsung::ProcessSamsung($et, { DirName => 'Samsung', RAF => $raf });
1664
+ }
1657
1665
  return -1 if $outfile and ($err or not $wasEnd);
1658
1666
  return 1; # this was a valid PNG/MNG/JNG image
1659
1667
  }
@@ -16,7 +16,7 @@ use strict;
16
16
  use vars qw($VERSION $AUTOLOAD);
17
17
  use Image::ExifTool qw(:DataAccess :Utils);
18
18
 
19
- $VERSION = '1.45';
19
+ $VERSION = '1.46';
20
20
 
21
21
  sub WritePS($$);
22
22
  sub ProcessPS($$;$);
@@ -156,15 +156,6 @@ sub AUTOLOAD
156
156
  return Image::ExifTool::DoAutoLoad($AUTOLOAD, @_);
157
157
  }
158
158
 
159
- #------------------------------------------------------------------------------
160
- # Is this a PC system
161
- # Returns: true for PC systems
162
- my %isPC = (MSWin32 => 1, os2 => 1, dos => 1, NetWare => 1, symbian => 1, cygwin => 1);
163
- sub IsPC()
164
- {
165
- return $isPC{$^O};
166
- }
167
-
168
159
  #------------------------------------------------------------------------------
169
160
  # Get image width or height
170
161
  # Inputs: 0) value list ref (ImageData, BoundingBox), 1) true to get height
@@ -284,7 +275,7 @@ sub GetNextLine($$)
284
275
  $$raf{PSEnd} and CheckPSEnd($raf, \$data);
285
276
  # split line if it contains other newline sequences
286
277
  if ($data =~ /$altnl/) {
287
- if (length($data) > 500000 and IsPC()) {
278
+ if (length($data) > 500000 and Image::ExifTool::IsPC()) {
288
279
  # patch for Windows memory problem
289
280
  unless ($changedNL) {
290
281
  $changedNL = $/;
@@ -537,7 +528,7 @@ sub ProcessPS($$;$)
537
528
  $raf->ReadLine($data) or last;
538
529
  # check for alternate newlines as efficiently as possible
539
530
  if ($data =~ /$altnl/) {
540
- if (length($data) > 500000 and IsPC()) {
531
+ if (length($data) > 500000 and Image::ExifTool::IsPC()) {
541
532
  # Windows can't split very long lines due to poor memory handling,
542
533
  # so re-read the file with the other newline character instead
543
534
  # (slower but uses less memory)
@@ -48,7 +48,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
48
48
  use Image::ExifTool::Exif;
49
49
  use Image::ExifTool::GPS;
50
50
 
51
- $VERSION = '2.98';
51
+ $VERSION = '3.02';
52
52
 
53
53
  sub ProcessMOV($$;$);
54
54
  sub ProcessKeys($$$);
@@ -6552,7 +6552,7 @@ my %userDefined = (
6552
6552
  PROCESS_PROC => \&ProcessKeys,
6553
6553
  WRITE_PROC => \&WriteKeys,
6554
6554
  CHECK_PROC => \&CheckQTValue,
6555
- VARS => { LONG_TAGS => 7 },
6555
+ VARS => { LONG_TAGS => 8 },
6556
6556
  WRITABLE => 1,
6557
6557
  # (not PREFERRED when writing)
6558
6558
  GROUPS => { 1 => 'Keys' },
@@ -6606,6 +6606,8 @@ my %userDefined = (
6606
6606
  PrintConv => '$val * 1e6 . " microseconds"',
6607
6607
  PrintConvInv => '$val =~ s/ .*//; $val * 1e-6',
6608
6608
  },
6609
+ # 'camera.focal_length.35mm_equivalent' - not top level (written to Keys in video track)
6610
+ # 'camera.lens_model' - not top level (written to Keys in video track)
6609
6611
  'location.ISO6709' => {
6610
6612
  Name => 'GPSCoordinates',
6611
6613
  Groups => { 2 => 'Location' },
@@ -6668,7 +6670,12 @@ my %userDefined = (
6668
6670
  #
6669
6671
  'com.apple.photos.captureMode' => 'CaptureMode',
6670
6672
  'com.android.version' => 'AndroidVersion',
6671
- 'com.android.capture.fps' => 'AndroidCaptureFPS',
6673
+ 'com.android.capture.fps' => { Name => 'AndroidCaptureFPS', Writable => 'float' },
6674
+ 'com.android.manufacturer' => 'AndroidMake',
6675
+ 'com.android.model' => 'AndroidModel',
6676
+ 'com.xiaomi.preview_video_cover' => { Name => 'XiaomiPreviewVideoCover', Writable => 'int32s' },
6677
+ 'xiaomi.exifInfo.videoinfo' => 'XiaomiExifInfo',
6678
+ 'com.xiaomi.hdr10' => { Name => 'XiaomiHDR10', Writable => 'int32s' },
6672
6679
  #
6673
6680
  # also seen
6674
6681
  #
@@ -9484,7 +9491,7 @@ sub ProcessKeys($$$)
9484
9491
  $$newInfo{KeysID} = $tag; # save original ID for use in family 7 group name
9485
9492
  AddTagToTable($itemList, $id, $newInfo);
9486
9493
  $msg or $msg = '';
9487
- $out and print $out "$$et{INDENT}Added ItemList Tag $id = ($ns) $tag$msg\n";
9494
+ $out and print $out "$$et{INDENT}Added ItemList Tag $id = ($ns) $full$msg\n";
9488
9495
  }
9489
9496
  $pos += $len;
9490
9497
  ++$index;
@@ -9521,7 +9528,7 @@ sub ProcessMOV($$;$)
9521
9528
  my $dirID = $$dirInfo{DirID} || '';
9522
9529
  my $charsetQuickTime = $et->Options('CharsetQuickTime');
9523
9530
  my ($buff, $tag, $size, $track, $isUserData, %triplet, $doDefaultLang, $index);
9524
- my ($dirEnd, $unkOpt, %saveOptions, $atomCount, $warnStr);
9531
+ my ($dirEnd, $unkOpt, %saveOptions, $atomCount, $warnStr, $trailer);
9525
9532
 
9526
9533
  my $topLevel = not $$et{InQuickTime};
9527
9534
  $$et{InQuickTime} = 1;
@@ -9550,6 +9557,17 @@ sub ProcessMOV($$;$)
9550
9557
  $tagTablePtr = GetTagTable('Image::ExifTool::QuickTime::Main');
9551
9558
  }
9552
9559
  ($size, $tag) = unpack('Na4', $buff);
9560
+ my $fast = $$et{OPTIONS}{FastScan} || 0;
9561
+ # check for Insta360 trailer
9562
+ if ($topLevel and not $fast) {
9563
+ my $pos = $raf->Tell();
9564
+ if ($raf->Seek(-40, 2) and $raf->Read($buff, 40) == 40 and
9565
+ substr($buff, 8) eq '8db42d694ccc418790edff439fe026bf')
9566
+ {
9567
+ $trailer = [ 'Insta360', $raf->Tell() - unpack('V',$buff) ];
9568
+ }
9569
+ $raf->Seek($pos,0) or return 0;
9570
+ }
9553
9571
  if ($dataPt) {
9554
9572
  $verbose and $et->VerboseDir($$dirInfo{DirName});
9555
9573
  } else {
@@ -9588,7 +9606,6 @@ sub ProcessMOV($$;$)
9588
9606
  # have XMP take priority except for HEIC
9589
9607
  $$et{PRIORITY_DIR} = 'XMP' unless $fileType and $fileType eq 'HEIC';
9590
9608
  }
9591
- my $fast = $$et{OPTIONS}{FastScan} || 0;
9592
9609
  $$raf{NoBuffer} = 1 if $fast; # disable buffering in FastScan mode
9593
9610
 
9594
9611
  my $ee = $$et{OPTIONS}{ExtractEmbedded};
@@ -9737,7 +9754,7 @@ sub ProcessMOV($$;$)
9737
9754
  if ($size > 0x2000000) { # start to get worried above 32 MiB
9738
9755
  # check for RIFF trailer (written by Auto-Vox dashcam)
9739
9756
  if ($buff =~ /^(gpsa|gps0|gsen|gsea)...\0/s) { # (yet seen only gpsa as first record)
9740
- $et->VPrint(0, "Found RIFF trailer");
9757
+ $et->VPrint(0, sprintf("Found RIFF trailer at offset 0x%x",$lastPos));
9741
9758
  if ($et->Options('ExtractEmbedded')) {
9742
9759
  $raf->Seek(-8, 1) or last; # seek back to start of trailer
9743
9760
  my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
@@ -9746,6 +9763,11 @@ sub ProcessMOV($$;$)
9746
9763
  EEWarn($et);
9747
9764
  }
9748
9765
  last;
9766
+ } elsif ($buff eq 'CCCCCCCC') {
9767
+ $et->VPrint(0, sprintf("Found Kenwood trailer at offset 0x%x",$lastPos));
9768
+ my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
9769
+ ProcessKenwoodTrailer($et, { RAF => $raf }, $tbl);
9770
+ last;
9749
9771
  }
9750
9772
  $ignore = 1;
9751
9773
  if ($tagInfo and not $$tagInfo{Unknown} and not $eeTag) {
@@ -10124,6 +10146,10 @@ ItemID: foreach $id (reverse sort { $a <=> $b } keys %$items) {
10124
10146
  $dataPos += $size + 8; # point to start of next atom data
10125
10147
  last if $dirEnd and $dataPos >= $dirEnd; # (note: ignores last value if 0 bytes)
10126
10148
  $lastPos = $raf->Tell() + $dirBase;
10149
+ if ($trailer and $lastPos >= $$trailer[1]) {
10150
+ $et->Warn(sprintf('%s trailer at offset 0x%x', @$trailer), 1);
10151
+ last;
10152
+ }
10127
10153
  $raf->Read($buff, 8) == 8 or last;
10128
10154
  $lastTag = $tag if $$tagTablePtr{$tag} and $tag ne 'free'; # (Insta360 sometimes puts free block before trailer)
10129
10155
  ($size, $tag) = unpack('Na4', $buff);
@@ -10132,14 +10158,10 @@ ItemID: foreach $id (reverse sort { $a <=> $b } keys %$items) {
10132
10158
  if ($warnStr) {
10133
10159
  # assume this is an unknown trailer if it comes immediately after
10134
10160
  # mdat or moov and has a tag name we don't recognize
10135
- if (($lastTag eq 'mdat' or $lastTag eq 'moov') and (not $$tagTablePtr{$tag} or
10136
- ref $$tagTablePtr{$tag} eq 'HASH' and $$tagTablePtr{$tag}{Unknown}))
10161
+ if (($lastTag eq 'mdat' or $lastTag eq 'moov') and
10162
+ (not $$tagTablePtr{$tag} or ref $$tagTablePtr{$tag} eq 'HASH' and $$tagTablePtr{$tag}{Unknown}))
10137
10163
  {
10138
- if ($size == 0x1000000 - 8 and $tag =~ /^(\x94\xc0\x7e\0|\0\x02\0\0)/) {
10139
- $et->Warn(sprintf('Insta360 trailer at offset 0x%x', $lastPos), 1);
10140
- } else {
10141
- $et->Warn('Unknown trailer with '.lcfirst($warnStr));
10142
- }
10164
+ $et->Warn('Unknown trailer with '.lcfirst($warnStr));
10143
10165
  } else {
10144
10166
  $et->Warn($warnStr);
10145
10167
  }
@@ -10166,7 +10188,10 @@ QTLang: foreach $tag (@{$$et{QTLang}}) {
10166
10188
  for ($i=0, $key=$name; $$infoHash{$key}; ++$i, $key="$name ($i)") {
10167
10189
  next QTLang if $et->GetGroup($key, 0) eq 'QuickTime';
10168
10190
  }
10169
- $et->FoundTag($tagInfo, $$et{VALUE}{$tag});
10191
+ $key = $et->FoundTag($tagInfo, $$et{VALUE}{$tag});
10192
+ # copy extra tag information (groups, etc) to the synthetic tag
10193
+ $$et{TAG_EXTRA}{$key} = $$et{TAG_EXTRA}{$tag};
10194
+ $et->VPrint(0, "(synthesized default-language tag for QuickTime:$$tagInfo{Name})");
10170
10195
  }
10171
10196
  delete $$et{QTLang};
10172
10197
  }